n8n listens on TCP port 5678 by default, so an n8n port conflict happens when another self-hosted app on the same machine has already claimed that port, and the fix is either to remap n8n’s host-side port in Docker (-p 5679:5678) or to change the port n8n binds to inside the container with the N8N_PORT environment variable. You’ll spot the problem right away because n8n dies on startup with EADDRINUSE: address already in use 0.0.0.0:5678, or Docker refuses with “port is already allocated.” The catch most people hit next: once you move the port, n8n keeps generating webhook URLs on the old address unless you also set WEBHOOK_URL, which quietly breaks every incoming webhook trigger you’ve built. Below is how to find the offending process, pick a new port that won’t collide again, and set up a reverse proxy so you never have to think about ports at all.
Which ports n8n actually uses on a self-hosted box
n8n only needs one port for the app itself, but a full self-hosted stack touches several. Knowing all of them saves you from fixing one conflict and walking straight into another.
Port 5678 is the big one. That’s the default for the editor UI, the REST API, and every webhook endpoint. n8n’s official documentation confirms N8N_PORT controls it, with N8N_LISTEN_ADDRESS controlling which network interface it binds to (0.0.0.0 by default, meaning every interface on the machine).
If you’re running n8n in queue mode, you’ve got more moving parts. The main instance still uses 5678. Each worker runs its own process, and n8n exposes a health check endpoint on workers when QUEUE_HEALTH_CHECK_ACTIVE is on, with a separate port setting for it.
Newer 1.x releases also ship a task runner broker that binds to its own port when task runners are turned on. Both of those numbers have changed across versions, so read the environment variables reference for the version tag you’re pulling rather than trusting a blog post from two years ago.
Then there are the dependencies. A production n8n setup normally runs PostgreSQL on 5432 and Redis on 6379 for queue mode. Those two are far more likely to collide than 5678 itself, because half the self-hosted world runs Postgres or Redis.
If you already have a Postgres container serving Nextcloud or Immich, spinning up a second one on the same host port fails instantly.
The default port is fine, the exposure isn’t
There’s a difference between the port n8n binds to inside its container and the port you publish on the host. In docker run -p 5678:5678, the left number is the host, the right number is the container. Changing the left number solves conflicts without touching n8n’s config at all.
That’s the cleaner fix in most cases, and it’s the one I reach for first.
Note: if you’re running n8n directly with npm or pm2 instead of Docker, there’s no mapping layer. The only lever you have is N8N_PORT, and any port below 1024 needs root privileges on Linux.
How to find out which app grabbed port 5678
Before changing anything, identify what’s holding the port. Guessing wastes an afternoon, and I’ve watched people move n8n three times because they never found the real culprit.
- On Linux, run
sudo ss -tulpn | grep 5678. This prints the protocol, the listening address, and the PID plus process name in the last column. If nothing comes back, the port is free and your problem is somewhere else. - On macOS, run
sudo lsof -i :5678. You’ll get the command name, PID, user, and connection state. macOS has its own quirk worth remembering: AirPlay Receiver in System Settings grabs port 5000, which trips people up when they move n8n to a “safe” round number. - On Windows, run
netstat -ano | findstr :5678in an elevated PowerShell. The last column is the PID. Match it in Task Manager’s Details tab to get a process name.
Once you know the owner, you have a real decision: move n8n, or move the other tool. My rule is to move whichever one has fewer external dependencies pointing at it. If the other app has a fixed client, a mobile app, or hardcoded webhooks, move n8n instead.
Fixing an n8n port conflict step by step
Time needed: about 10 minutes for the Docker route, 20 if you’re also updating webhook URLs.
Difficulty: beginner for the port change, intermediate if OAuth credentials are involved.
- Stop the n8n container with
docker stop n8n, then remove it withdocker rm n8n. You need the container gone before you can republish it on a different host port. Your data lives in the mounted volume, not the container, so nothing is lost as long as you kept-v n8n_data:/home/node/.n8nin the original command. - Pick a new host port outside the ephemeral range. On most Linux systems the kernel hands out ephemeral ports from 32768 upward, so anything in the 5000 to 9999 band is safer for a fixed service. Confirm your choice is free using the check from the previous section before committing to it.
- Republish n8n on the new host port, keeping the container port at 5678. For example:
docker run -d --name n8n -p 5679:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n. n8n still thinks it’s on 5678 internally, which keeps its config untouched. - Set
WEBHOOK_URLto the address your traffic will actually arrive on. Add-e WEBHOOK_URL=http://your-host:5679/to the run command. Skip this and n8n will keep printing and registering webhook URLs on port 5678, which no longer exists on the host. This is the step that causes most of the “my workflow worked yesterday” support threads. - Set
N8N_PORTinstead if you’re not using Docker. AddN8N_PORT=5679to your environment file or systemd unit, restart the service, and confirm withss -tulpn | grep 5679that it’s listening on the new number. - Re-save any workflow that uses a Webhook or Wait node, then re-copy its production URL. n8n builds those URLs from the configured base address. Old copies pasted into Stripe, GitHub, or a form builder still point at the dead port and need updating on the sending side.
Warning: if you’ve connected OAuth2 credentials (Google, Microsoft, Slack), those services store a redirect URI that includes your n8n URL and port. Changing the port invalidates them. You’ll need to update the redirect URI in each provider’s developer console and reconnect the credential, which takes a few minutes per service.
A timing note worth planning around: DNS and reverse proxy changes propagate fast on your own network, but third-party webhook providers vary. Some retry failed deliveries for hours, some drop them after a couple of attempts. If you’re moving a port on a workflow handling payments or order events, do it during a quiet window and watch the executions list for failures afterwards.
The self-hosted tools most likely to fight n8n for a port
Very few popular apps use 5678 as a default, which is good news. The real collisions happen when you’ve already remapped n8n to a “nicer” port, or when n8n’s supporting services meet an existing database.
Here’s what commonly sits on a shared homelab or VPS, and the default ports to watch:
| Tool | Default port(s) | Collides with |
|---|---|---|
| Grafana | 3000 | A remapped n8n on 3000 |
| Uptime Kuma | 3001 | A remapped n8n on 3001 |
| Node-RED | 1880 | Rarely, but both are automation tools people run together |
| Portainer | 9000, 9443 | A remapped n8n on 9000 |
| Home Assistant | 8123 | Rarely |
| Nginx Proxy Manager | 80, 81, 443 | Anything you publish on 80 or 443 |
| Traefik | 80, 443, 8080 | Same, plus its dashboard |
| Jenkins / Adminer / code-server | 8080 | Very common 8080 pileup |
| PostgreSQL | 5432 | n8n’s own database container |
| Redis | 6379 | n8n queue mode |
The pattern is clear once you see it laid out. n8n on its stock port is a quiet neighbour. The trouble starts when you standardise everything onto 8080 or 3000 because those numbers feel familiar, then run a second app that wants the same one.
Postgres deserves special attention. If you already run a Postgres container for another service, don’t publish a second one on host port 5432. Put both containers on the same Docker network and let n8n reach the database by container name on the internal port, with no host publishing at all.
That’s the tidiest arrangement, and it also stops your database from being reachable from the wider network by accident. The same logic applies to Redis.
While you’re stacking services on one box, keep an eye on what else that machine is carrying. Resource contention shows up as slow workflow executions long before you run out of ports, and it’s often the real reason to think about moving up to a virtual server with room to breathe.
Docker Compose changes the shape of the problem
In Compose, ports: publishes to the host and expose: only opens the port to other containers on the same network. Most n8n port conflicts in a Compose stack come from publishing things that never needed publishing. Your Postgres, Redis, and worker containers don’t need host ports.
Only n8n’s editor does, and even that stops being true once a reverse proxy is in front.
Rewriting a Compose file this way usually removes three or four conflicts at once, and it shrinks the attack surface at the same time.
Putting a reverse proxy in front removes the port juggling entirely
The permanent fix for n8n port conflicts isn’t a better port number. It’s giving every self-hosted app its own hostname on ports 80 and 443, and letting a reverse proxy sort out which container gets which request.
The setup looks like this. One proxy container (Nginx Proxy Manager, Traefik, or Caddy) publishes 80 and 443 to the host. Nothing else publishes anything. n8n sits on an internal Docker network still listening on 5678, invisible from outside.
The proxy matches n8n.yourdomain.com and forwards to http://n8n:5678. Grafana gets grafana.yourdomain.com, Uptime Kuma gets its own, and none of them ever meet.
Three settings matter on the n8n side when you do this:
N8N_HOST should be the public hostname, like n8n.yourdomain.com. N8N_PROTOCOL should be https so generated links use the right scheme. WEBHOOK_URL should be the full public base URL, https://n8n.yourdomain.com/. Get these right and every webhook URL n8n hands you is already correct, with no port number in sight.
There’s one more setting people miss. Behind a proxy, n8n needs to know how many hops sit between it and the client so it reads the real IP from the forwarded headers. n8n’s docs cover this under proxy hop configuration. Skip it and rate limiting or IP-based logic in your workflows reads the proxy’s address instead of the caller’s.
If you’re pointing a subdomain at your automation server for the first time, the DNS side is worth reading up on, particularly how host records behave when the parent domain already resolves elsewhere. And since webhook providers refuse plain HTTP in a lot of cases, you’ll want a certificate for that hostname before you flip anything over. Most proxies handle Let’s Encrypt issuance automatically once the DNS record resolves.
Note: a reverse proxy fixes external collisions, not internal ones. Two containers can both listen on 5678 internally as long as neither publishes to the host, because each container has its own network namespace. Docker’s own networking documentation explains why that works.
Things people get wrong about n8n and ports
Mix-up: Changing N8N_PORT in a Docker Compose file is enough to move n8n.
Reality: N8N_PORT changes the port inside the container. If your ports: line still says 5678:5678, Docker forwards host 5678 to container 5678, and nothing is listening there anymore. Either change both, or change neither and remap only the host side.
Mix-up: A port conflict and a firewall block look the same from outside.
Reality: They produce different symptoms. A port conflict stops n8n from starting at all, and you’ll see EADDRINUSE in docker logs n8n. A firewall block lets n8n start normally but the browser hangs or times out.
Check the container logs first; that one glance tells you which problem you have.
Mix-up: Binding n8n to 0.0.0.0 is required for it to work.
Reality: 0.0.0.0 is the default because it accepts connections on every interface. If n8n only ever gets traffic from a reverse proxy on the same host, N8N_LISTEN_ADDRESS=127.0.0.1 keeps it off the network entirely. That’s a sensible tightening for anything exposed to the internet, and worth writing down in your setup notes so the next person doesn’t undo it.
Mix-up: Any free port will do.
Reality: On Windows, Hyper-V and WSL2 reserve blocks of ports that show as free but refuse binding. Run netsh int ipv4 show excludedportrange protocol=tcp in an admin prompt to see the reserved ranges before you pick a number.
What to do when n8n still won’t start after you’ve moved it
Problem: Docker says “Bind for 0.0.0.0:5678 failed: port is already allocated” even though docker ps shows nothing on that port.
Fix: Run docker ps -a to catch stopped containers still holding the mapping, remove the old one with docker rm, then retry. If the message persists, restart the Docker daemon; occasionally a container exits without releasing its published port cleanly.
Problem: n8n starts, the UI loads, but webhook test URLs return 404 from the outside.
Fix: Check WEBHOOK_URL matches the address traffic actually arrives on, including protocol and port. Then confirm your reverse proxy forwards the full path rather than stripping a prefix. A proxy rule that rewrites /webhook/abc to /abc will produce exactly this symptom.
Problem: The container starts, then restarts in a loop every few seconds.
Fix: Read docker logs n8n --tail 50. A port conflict shows as EADDRINUSE. A database problem shows as a connection refused error naming your Postgres host.
A permissions problem on the mounted volume shows as EACCES. Each has a different fix, and the log line tells you which one you’re dealing with.
Problem: Everything works on the host but not from another machine on the network.
Fix: Confirm n8n isn’t bound to 127.0.0.1, then check the host firewall. On Ubuntu, sudo ufw status lists allowed ports; add the new one with sudo ufw allow 5679/tcp. On a cloud VPS there’s usually a separate provider-level firewall to update as well.
Problem: You changed the port and now OAuth credentials show as disconnected.
Fix: Update the redirect URI in each provider’s app settings to the new n8n URL, then reconnect the credential inside n8n. There’s no way around doing this per service, which is a solid argument for settling on a hostname-based setup once and never changing the port again.
What this means for your setup
If you’re running two or three self-hosted tools, remapping the host port is fine. It takes ten minutes, it’s reversible, and the only real trap is forgetting WEBHOOK_URL. Write the new port in a note somewhere so you’re not rediscovering it in six months.
If you’re running more than that, or you plan to, put the reverse proxy in now. Every tool gets a subdomain, port conflicts stop being a category of problem, and your webhook URLs stay stable no matter how the containers underneath get rearranged. The half hour it costs pays for itself the first time you add a service.
One thing worth being straight about: none of this helps if the machine underneath is too small. n8n with Postgres, Redis, and a couple of workers wants real memory, and shared hosting won’t run Docker containers at all. A VPS with root access is the baseline for a self-hosted n8n stack, and if you’re planning to keep the box for a while, set up regular restore points before you start moving ports around. Workflow data lives in that Postgres volume, and a bad Compose edit can take it with it.
Hostinger’s VPS plans give you the root access and Docker support this needs, and you can claim the current 85% discount with code hHostCouponHub if you’re setting up a fresh box for n8n.
Frequently asked questions
What is the default port for n8n?
n8n uses TCP port 5678 by default for the editor UI, the REST API, and webhook endpoints. You change it with the N8N_PORT environment variable, or by remapping the host side of the Docker publish flag. The default rarely conflicts with mainstream self-hosted apps, though it’s the conventional port for Python debugpy sessions on developer machines.
Can I run n8n and another Docker container on the same port?
Not on the same host port, no. Two containers can both listen on 5678 internally without any issue, because each has its own network namespace, but only one can publish to a given host port at a time. Put both behind a reverse proxy and give each a hostname, and the internal port numbers stop mattering.
Does changing the n8n port break existing workflows?
The workflows themselves stay intact, but anything holding an old webhook URL breaks. That covers third-party services you’ve registered webhooks with, OAuth2 redirect URIs stored at the provider, and any hardcoded URLs in other systems. Set WEBHOOK_URL to the new address and re-copy the production URL from each Webhook node.
How do I stop port conflicts happening again?
Publish as few host ports as possible. Run one reverse proxy on 80 and 443, keep databases and Redis on an internal Docker network with no ports: entry, and give each app its own subdomain. Keep a short list of which host ports are taken by which service, and check it before adding anything new.
Ready to get your stack running cleanly?
Sort the port conflict first, set WEBHOOK_URL while you’re in there, and think about a reverse proxy before you add the next tool. If you need a server with enough headroom for n8n plus everything else you’re running, Hostinger’s VPS range is a reasonable place to start, and the current discount runs at 85% off with code hHostCouponHub on new plans.
This page contains affiliate links. If you purchase through the links on this page, we may earn a commission, at no extra cost to you.





1 thought on “Fix n8n Port Conflicts With Other Self-Hosted Tools”