Dynamic port range
Look back at the ss output from Introduction to ports and protocols: a browser's outbound connection showed a local port like 51342 — a number nobody configured, chose, or documented anywhere. That's the third and last port range, and it works completely differently from the two before it.
What the dynamic range is for
Ports 49152 through 65535 are not assigned to any specific service at all. Instead, the operating system's networking stack hands one out automatically, on demand, whenever a program needs to initiate an outbound connection and hasn't asked for a particular source port.
This is exactly what happened in the browser example: your browser didn't choose port 51342 for its connection to a web server. The kernel assigned it silently, purely so the connection to the server's port 443 would have a distinct, unique source socket. These are also called ephemeral ports, because they exist only for the lifetime of one connection — once it closes, the OS eventually reclaims the number and can hand it out again for something completely unrelated.
Why this range makes many simultaneous connections possible
Recall from Introduction to ports and protocols that a connection is uniquely identified by the combination of both ends' IP address and port. A server listening on a fixed destination port, say 443, can be reached by thousands of clients at once specifically because each client's operating system gives it a different ephemeral source port. Even a single client can open many simultaneous connections to the very same server on the very same destination port, as long as each gets its own distinct source port:
Client 203.0.113.5:51342 <---> Server 198.51.100.10:443 (connection 1)
Client 203.0.113.5:51343 <---> Server 198.51.100.10:443 (connection 2)
Client 203.0.113.5:51344 <---> Server 198.51.100.10:443 (connection 3)
A modern web page routinely opens several of these at once — the page itself, its stylesheets, its images, its scripts — and the ephemeral range is what lets the kernel track each as a distinct conversation with no coordination from the application at all.
How the OS picks a port, and what range it picks from
When a program opens an outbound connection without binding to a specific local port — the overwhelmingly common case for client applications — the kernel takes the next available number from its configured ephemeral range. On Linux that range is a tunable you can read directly:
Two things are worth noticing in that output. First, the numbers on your own machine may differ, and that's fine. Second, 32768–60999 is not IANA's recommended 49152–65535 — it's narrower and shifted lower. This is the long-standing Linux default, not a misconfiguration, and it's a good reminder that IANA's range is a recommendation rather than something operating systems are bound by. Windows and macOS ship their own different defaults. If you ever need to reason about ephemeral ports on a specific host, read the value rather than assuming the standard.
That range size has a direct consequence: 60999 − 32768 + 1 gives roughly 28,000 available ephemeral ports per local IP address, per transport protocol. For a laptop that's effectively unlimited. For a busy server making outbound connections, it's a ceiling — and an administrator can raise it by widening the range, though as the scenario below shows, that's rarely the right first move.
Recognizing a dynamic port in output
Going back to the established connection from earlier in this module:
51342 is a dynamic port assigned for this one outbound connection. There is no "service" on it, and looking it up in any registry will tell you nothing, because nothing is running on it in the sense that a listening service runs on a port. It exists only as this connection's local half of the socket pair, and it disappears when the connection does. Contrast 443 on the remote side: that one is meaningful, because a server chose to listen there deliberately and predictably.
The rule of thumb for reading socket tables: a high, seemingly random number in the source column of an outbound connection is almost certainly ephemeral and tells you nothing. The same kind of number as a destination, or on a LISTENing socket, is a deliberate choice and worth looking up.
An ephemeral port isn't a service — it's a receipt for one conversation. It never gets registered, never gets looked up, and stops meaning anything the moment the connection that used it closes. If an interviewer asks what's "running" on port 51342 in a socket table, the correct answer is that the question itself is the wrong one to ask about a source port.
There's a corollary worth stating, because people occasionally try it: don't bind a client to a fixed source port "for consistency." Doing so throws away the one property that keeps concurrent connections distinct, and you'll get collisions between connections the kernel would otherwise have separated automatically.
Practical scenario: a scraper that stops connecting
A data-collection service runs fine for twenty minutes, then new outbound connections start failing with EADDRNOTAVAIL — "cannot assign requested address" — while the machine's network is otherwise healthy. It can still be pinged, still serves inbound traffic, and has plenty of CPU and memory free.
This is ephemeral port exhaustion, and the arithmetic explains it. The service opens thousands of short-lived TCP connections to the same destination and closes each one immediately. When a TCP connection closes, the closing side normally keeps the socket in a TIME_WAIT state for a period — typically around a minute — so that any straggling packets from the finished connection can't be mistaken for part of a new one reusing the same port pair. Those sockets still hold their port.
You can see the state pile up:
Against the ~28,000 ports the range allows, 24,518 of them stuck in TIME_WAIT is the whole problem. Widening ip_local_port_range buys some headroom and is a reasonable stopgap, but it treats the symptom: the real issue is a client opening a new connection for every single request.
The fixes, in the order worth trying:
- Reuse connections. Enable HTTP keep-alive and use a connection pool so one connection serves many requests. This usually eliminates the problem outright rather than deferring it.
- Limit concurrency. A bounded worker pool caps how many connections can exist at once.
- Widen the range, if the workload genuinely needs tens of thousands of simultaneous connections rather than merely creating them carelessly.
- Add source addresses. Ephemeral ports are counted per local IP, so a second address doubles the space — but this is infrastructure complexity to solve an application problem, and it belongs last.
The general lesson is that ephemeral port exhaustion is nearly always a signal about connection lifecycle, not about the port range being too small.
Common mistakes
- Looking up what "service" runs on an ephemeral source port. There isn't one. It's a temporary label for one end of one connection.
- Assuming the ephemeral range is the same everywhere. IANA recommends 49152–65535; Linux, Windows, and macOS all ship different defaults, and administrators change them.
- Reading
EADDRNOTAVAILor a sudden inability to make outbound connections as a network or firewall fault. If inbound traffic works and only new outbound connections fail, suspect port exhaustion before you touch a firewall rule. - Raising the range as the first response to exhaustion. It delays the failure. Connection reuse removes it.
Practice exercises
- Read your own machine's ephemeral range with
cat /proc/sys/net/ipv4/ip_local_port_rangeand compare it against IANA's 49152–65535. Calculate how many ports your machine actually has available per local address. - Open several tabs to the same website, then run
ss -tnand find the multiple simultaneous connections to that site's address. Confirm each one has a distinct source port and an identical destination port. - Explain why a server handling ten thousand simultaneous clients on port 443 doesn't run out of room, even though every one of those clients connects to the same destination port — then explain why the client side of that same picture is the side that can run out.
Exercise 3 is the asymmetry this whole sub-module has been circling: a listening port is a fixed, published address, while a source port is a disposable label the kernel issues so replies can find their way home. Both halves are needed for a connection to be unambiguous.
And that principle is about to do much more work than it looks. If a source port is what distinguishes one connection from another, then a device sitting between your machine and the internet could rewrite addresses and ports on the way through — and use exactly that pairing to route each reply back to the right host behind it. That's precisely how an entire household shares one public address, which is where Public vs Private IP picks up.
Sources
- IANA, Service Name and Transport Protocol Port Number Registry
- IETF, RFC 6056 – Recommendations for Transport-Protocol Port Randomization
- IETF, RFC 9293 – Transmission Control Protocol (TCP) — defines the
TIME_WAITstate and why it exists. - Linux kernel documentation, IP sysctl parameters —
ip_local_port_range.