This cheatsheet lists the port numbers developers and sysadmins look up most often, grouped by job, plus the port ranges and a few commands for checking a port. A port is a 16-bit number, so the valid range is 0 to 65535, and TCP and UDP each have their own separate set of 65,536. The confusion it clears up: some numbers below are IANA assignments, and some are only common defaults that the registry does not list for that product.
| Range | Name | Notes |
|---|---|---|
| 0-1023 | System Ports (well-known) | Assigned by IANA. Unix systems usually need elevated rights to listen here |
| 1024-49151 | User Ports (registered) | Assigned by IANA on request |
| 49152-65535 | Dynamic Ports (private, ephemeral) | Never assigned. Meant for the client side of a connection |
Linux does not use the IANA dynamic range as is. On the machine used for this sheet, /proc/sys/net/ipv4/ip_local_port_range held 32768 60999.
| Port | Typical transport | Service | Notes |
|---|---|---|---|
| 22 | TCP | SSH | Also registered for UDP, but SSH uses TCP |
| 23 | TCP | Telnet | Plain text, avoid |
| 80 | TCP | HTTP | Registered names: http, www, www-http |
| 443 | TCP, UDP | HTTPS | IANA lists both transports |
| 8080 | TCP | HTTP alternate | Registered as http-alt |
| 8443 | TCP | Alternate HTTPS | IANA name is pcsync-https; used by convention for HTTPS |
| 3389 | TCP, UDP | Remote Desktop (ms-wbt-server) | |
| 5900 | TCP | VNC (rfb) |
| Port | Service | Notes |
|---|---|---|
| 25 | SMTP | Server to server relay |
| 587 | Submission | Mail clients sending through their provider |
| 465 | Submissions | SMTP over TLS from the start |
| 110 | POP3 | Plain |
| 995 | POP3S | POP3 over TLS |
| 143 | IMAP | Plain. Only TCP is assigned; UDP is reserved |
| 993 | IMAPS | IMAP over TLS |
| Port | Typical transport | Service |
|---|---|---|
| 53 | TCP, UDP | DNS |
| 853 | TCP, UDP | DNS over TLS (TCP), DTLS or QUIC (UDP) |
| 123 | UDP, TCP | NTP |
| 67, 68 | UDP | DHCP server and client (registered as bootps and bootpc) |
| 69 | UDP | TFTP |
| 21 | TCP | FTP control |
| 20 | TCP | FTP data |
| 445 | TCP | SMB (microsoft-ds) |
| 2049 | TCP, UDP | NFS |
| 873 | TCP | rsync daemon |
| 389 | TCP, UDP | LDAP |
| 636 | TCP | LDAPS |
| 161, 162 | UDP | SNMP queries and traps |
| 514 | UDP | Syslog |
| Port | Service | Registered by IANA? |
|---|---|---|
| 3306 | MySQL | Yes |
| 5432 | PostgreSQL | Yes |
| 1433 | Microsoft SQL Server | Yes |
| 6379 | Redis | Yes, TCP only |
| 27017 | MongoDB | Yes, TCP only |
| 11211 | Memcached | Yes |
| 5672 | RabbitMQ and AMQP | Yes (amqp) |
| 5671 | AMQP over TLS | Yes (amqps) |
| 1883, 8883 | MQTT, MQTT over TLS | Yes |
| 5984 | CouchDB | Yes |
| 1521 | Oracle Database default | No. IANA lists ncube-lm |
| 9200 | Elasticsearch HTTP default | No. IANA lists wap-wsp |
| Port | Service | Registered by IANA? |
|---|---|---|
| 2375 | Docker API, unencrypted | Yes (docker) |
| 2376 | Docker API over TLS | Yes (docker-s) |
| 6443 | Kubernetes API server default | No. IANA lists sun-sr-https |
| 51820 | WireGuard default | No entry found in the registry |
| 1194 | OpenVPN | Yes |
| 500, 4500 | IPsec IKE and NAT traversal | Yes, UDP |
| 179 | BGP | Yes |
| 3478 | STUN and TURN | Yes |
| 5060 | SIP | Yes |
| Fact | Value | Source |
|---|---|---|
| Port field size | 16 bits, so 0 to 65535 | TCP and UDP headers |
| Smallest UDP length field | 8 octets, the header alone | RFC 768 |
| TCP header length | Counted in 32-bit words in the Data Offset field | RFC 9293 |
| Source port in UDP | Optional. A zero means none | RFC 768 |
A connection is identified by four values: source address, source port, destination address and destination port. That is why a server on port 443 can talk to thousands of clients at once, since each client brings a different source port.
import socket
for n in ['http', 'https', 'ssh', 'smtp', 'domain', 'postgresql', 'mysql']:
print(n, socket.getservbyname(n, 'tcp'))
print(socket.getservbyport(53, 'udp'))
Output:
http 80
https 443
ssh 22
smtp 25
domain 53
postgresql 5432
mysql 3306
domain
Use this when a script has a service name and needs the number. It reads the local services file, so the answer depends on the machine.
ss -ltn 'sport = :18080'
Output with a test listener running:
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 127.0.0.1:18080 0.0.0.0:*
Use -l for listening sockets, -t for TCP and -u for UDP. Add -p to see the owning process, which may need root.
nc -zv 127.0.0.1 18080
nc -zv 127.0.0.1 18081
Output:
Connection to 127.0.0.1 18080 port [tcp/*] succeeded!
nc: connect to 127.0.0.1 port 18081 (tcp) failed: Connection refused
The flag -z scans without sending data. A refused connection means the host answered and nothing listens. A timeout usually means a firewall dropped the packet.
import socket
s = socket.socket()
s.bind(('127.0.0.1', 0))
print(s.getsockname()[1] >= 1024)
Output:
True
Binding to port 0 makes the kernel choose an unused port. Read the real number back with getsockname(), which is how test suites avoid port clashes.
import socket
a = socket.socket(); a.bind(('127.0.0.1', 0)); a.listen()
p = a.getsockname()[1]
b = socket.socket()
try:
b.bind(('127.0.0.1', p))
except OSError as e:
print(e)
u = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
u.bind(('127.0.0.1', p))
print('udp same number bind ok')
Output:
[Errno 98] Address already in use (Linux; Windows reports WinError 10048)
udp same number bind ok
Two TCP listeners cannot share an address and port, but a UDP socket can use the same number as a TCP one.
for (const u of ['http://example.com:80/', 'https://example.com:443/', 'https://example.com:8443/', 'http://example.com:443/']) {
const x = new URL(u);
console.log(u, '=> port:', JSON.stringify(x.port), 'host:', x.host);
}
Output:
http://example.com:80/ => port: "" host: example.com
https://example.com:443/ => port: "" host: example.com
https://example.com:8443/ => port: "8443" host: example.com:8443
http://example.com:443/ => port: "443" host: example.com:443
The URL class drops a port that matches the scheme default and returns an empty string. Code that reads url.port to build a socket address must fall back to 80 or 443 itself.
OverflowError: bind(): port must be 0-65535. for 65536.Address already in use error appears only within the same transport and address.Connection refused comes from the target host, which means the packet arrived. A silent timeout points to a filter in between.new URL('https://example.com:443/').port is an empty string, and a port above 65535 throws ERR_INVALID_URL. Use a default-port lookup before connecting.