Nginx Error: 'no port in upstream' — Cause, Fix, and Troubleshooting Guide
Fix nginx [emerg] no port in upstream 'backend': an upstream server entry has no port and no default applies. Add the explicit :PORT and reload.
- #nginx
- #web-server
- #troubleshooting
- #config
Stuck on this NGINX error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
What this error means
no port in upstream "<name>" is a configuration-parse error. When a server entry inside an upstream {} block gives only an address with no port, NGINX needs a way to infer one. In an http {} proxy that address is fine only when a scheme in proxy_pass supplies a default (http:// → 80, https:// → 443). In the stream {} context (raw TCP/UDP), and whenever no default can be derived, the port is mandatory — and NGINX aborts the load with this emerg.
nginx: [emerg] no port in upstream "backend" in /etc/nginx/conf.d/upstream.conf:2
nginx: configuration file /etc/nginx/nginx.conf test failed
The cited line is the server entry missing the port. Like every parse [emerg], a reload keeps the old config running and a cold start fails, so the proxied service goes unserved on a fresh boot.
How it presents
nginx -tfails with[emerg] no port in upstream "backend".- The cited line is an
upstreamserverdirective such asserver 10.0.3.20;. systemctl reload nginxfails; a coldstartleaves NGINX dead.- Most common in
stream {}(TCP/UDP) upstreams, where no scheme default exists. - Also appears in
httpupstreams referenced by aproxy_passthat carries no scheme/port to fall back on. - Started right after adding a backend host, editing an
upstreamblock, or migrating anhttpproxy tostream.
Tracing the connection
Validate first; the emerg names the upstream and the file:line.
sudo nginx -t
Look at the cited upstream block with line numbers:
sed -n '1,10p' /etc/nginx/conf.d/upstream.conf | cat -n
Find every upstream server entry that has no :port across the tree:
grep -RnE '^\s*server\s+[A-Za-z0-9._-]+\s*;' /etc/nginx/ | grep -vE ':[0-9]+'
Confirm which context the block lives in — stream requires an explicit port:
sudo nginx -T | grep -nE 'stream\s*\{|upstream\s|proxy_pass'
Check how the upstream is referenced, since a scheme in proxy_pass changes whether a default exists:
grep -RnE 'proxy_pass' /etc/nginx/
Network path causes
- Stream upstream without a port —
stream {}proxies raw TCP/UDP with no notion of HTTP default ports, so everyserverentry must beip:port. - Bare host copied from notes —
server 10.0.3.20;pasted without the:8080suffix. proxy_passto a named upstream with no scheme — pointingproxy_pass backend;(or via a variable) at an upstream whose members lack ports leaves nothing to default from.- DNS name without a port —
server backend.example.com;in a context that requires an explicit port. - Dropped port during templating — a generated config emitted the address but the port variable was empty.
- Wrong context assumption — a block written for
http(wherehttp://would default to 80) reused verbatim understream, where no default applies.
Remediation steps
Add the explicit port to each upstream server entry. For a stream {} (TCP/UDP) proxy, the port is always required:
stream {
upstream backend {
server 10.0.3.20:5432; # explicit port is mandatory in stream
server 10.0.3.21:5432;
}
server {
listen 5432;
proxy_pass backend;
}
}
For an http {} proxy, either add the port to each member or make the default explicit via the proxy_pass scheme:
http {
upstream backend {
server 10.0.3.20:8080; # explicit port
server 10.0.3.21:8080;
}
server {
location / {
proxy_pass http://backend; # scheme is fine, but members should still carry ports
}
}
}
If a member must stay portless, ensure the proxy_pass scheme supplies the default (http:// → 80, https:// → 443) and that you are in the http context — never rely on this in stream. Being explicit avoids ambiguity:
upstream backend {
server backend.example.com:443; # name plus explicit port
}
Validate and reload:
sudo nginx -t && sudo systemctl reload nginx
Keeping the path healthy
- The
stream {}context has no HTTP default ports — everyserverentry needsip:port, always. - Prefer explicit ports even in
httpupstreams; relying on theproxy_passscheme default is easy to break when the block is reused elsewhere. - A named upstream referenced by
proxy_pass backend;(no scheme) offers no default to fall back on — give members ports. - Grep for portless upstream entries after any backend change; one bare host fails the whole config.
- Keep port numbers in variables/templates required, not optional, so an empty value fails at generation rather than at NGINX load.
- Watch out when migrating an
httpproxy tostream: identical-lookingserverlines that worked before now need explicit ports.
Related connectivity errors
- Nginx Error Host Not Found In Upstream — a related upstream parse failure, but from an unresolvable hostname rather than a missing port.
- Nginx Error No Live Upstreams — a runtime upstream failure to rule out once the block parses cleanly.
- Nginx Error Invalid Number Of Arguments — another malformed-directive
[emerg]common when editingserver/upstreamlines.
See the NGINX category for more guides.
Fixed it? Get 500 NGINX & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.