Skip to content

Registered ports

Not every service that needs a predictable port number is old enough, or universal enough, to deserve a spot in the well-known ports range. Databases, message queues, and application servers still benefit from a consistent, documented port so administrators and client software know where to find them — that's what the registered ports range, 1024 through 49151, is for.

What "registered" means here

Any organization or individual can ask IANA to register a specific port number for their application, and IANA maintains that assignment in its public registry. But unlike the well-known range, enforcement is much looser. IANA doesn't verify that only the registered application ever uses that number, and plenty of software in this range runs on its assigned port purely by convention — the same way well-known services do, just without the historical weight or the root-privilege requirement.

That missing privilege requirement is the practical difference. Ports in this range don't need elevated permissions to bind to on Linux: any regular user process can listen on 5432 or 8080 without root. It's the main reason so many application servers, databases, and development tools default here — they're designed to run as ordinary application processes, not as system services with administrative rights.

The flip side is that the range offers no protection whatsoever. Anyone can bind port 5432 as an unprivileged user, which means that if PostgreSQL isn't running, some entirely unrelated program can end up listening there. Treat "connection succeeded on 5432" as evidence that something answered, not proof that you reached a database.

Ports worth recognizing

Port Service Notes
3306 MySQL / MariaDB Default database port
5432 PostgreSQL Default database port
6379 Redis Default in-memory data store port
8080 Common HTTP alternate Widely used for development servers, proxies
8443 Common HTTPS alternate TLS-secured alternate to 8080
27017 MongoDB Default database port
5672 AMQP (RabbitMQ) Message queue protocol
9200 Elasticsearch Default HTTP API port

None of these assignments carry the weight that decades of client defaults give port 22. They're documented defaults that most deployments happen to follow, which makes them worth recognizing on sight during troubleshooting or in a packet capture — but not something to rely on. Production databases get moved to non-default ports routinely, for security or because one host runs several instances, which is why a port number belongs in your application's configuration rather than hardcoded as a constant.

Practical scenario: port 8080 is already taken

If you've done backend development you've hit this. Two services both default to 8080; you start the second one and it dies immediately:

Error: listen EADDRINUSE: address already in use 0.0.0.0:8080

This is neither a routing problem nor a firewall problem, and no amount of network debugging will help. A listening socket is claimed by exactly one process at a time — same protocol, same local address, same port — and the kernel is refusing to hand it to a second one. The fix starts with finding out who already has it:

sudo ss -tlnp | grep ':8080'
LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=1842,fd=91))

Everything you need is in that line: a Java process, PID 1842, holding 0.0.0.0:8080. Now the decision is concrete rather than a guess — stop that service, move your new one to a different port, or put both behind a reverse proxy (a server that accepts all incoming requests on one port and forwards each to the right backend based on hostname or URL path) so they can coexist on 80 and 443.

Note the 0.0.0.0 in the local address, because it changes what counts as a conflict. A process bound to 127.0.0.1:8080 and another bound to 192.168.1.10:8080 can coexist — different local addresses, different sockets. But 0.0.0.0:8080 claims the port on every address, so it collides with both. When a port conflict appears where you didn't expect one, the local address column is usually the explanation.

Practice exercises

  1. Start any local development server on your machine — a simple HTTP server, a database, whatever you have — and use sudo ss -tlnp to confirm which port it bound to, which local address, and which process owns it.
  2. Deliberately start two processes configured for the same port and read the error message closely. What does it tell you, and what does it not tell you about the process already holding the port?
  3. Look up port 27017 in IANA's registry and confirm it matches this article's table. Then look up 6379 and note whether the registry's entry matches how the port is actually used in practice.

Exercise 3 makes the point about this range better than any explanation: registration is documentation, not enforcement, and the gap between the two is sometimes visible right in the registry. Which raises a question about the numbers above 49151 — if the registered range is already loosely governed, what could the last band possibly be for? The answer is that nothing is assigned there at all, and that's precisely the point: Dynamic port range.

A follow-up an interviewer may ask

If you explain that registered ports don't require root and aren't strictly enforced, a natural follow-up is: "so what actually stops two different companies' software from colliding on the same registered port?" The honest answer is: nothing, structurally. IANA's registration reduces the odds of a collision on any given host, since well-behaved software tends to check the registry before picking a default. But two unrelated pieces of software can both default to, say, port 9000, and the only thing that decides which one wins on a given machine is which process calls bind() first — the kernel doesn't know or care about IANA's registry at all. That's a meaningfully different guarantee from well-known ports, where an actual OS-level permission check backs the convention up.

Sources