Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for NGINX By James Joyner IV · · 8 min read Last reviewed Jul 2026

Nginx Error: 'no port in upstream' — Cause, Fix, and Troubleshooting Guide

Quick answer

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
Free toolkit

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 -t fails with [emerg] no port in upstream "backend".
  • The cited line is an upstream server directive such as server 10.0.3.20;.
  • systemctl reload nginx fails; a cold start leaves NGINX dead.
  • Most common in stream {} (TCP/UDP) upstreams, where no scheme default exists.
  • Also appears in http upstreams referenced by a proxy_pass that carries no scheme/port to fall back on.
  • Started right after adding a backend host, editing an upstream block, or migrating an http proxy to stream.

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 portstream {} proxies raw TCP/UDP with no notion of HTTP default ports, so every server entry must be ip:port.
  • Bare host copied from notesserver 10.0.3.20; pasted without the :8080 suffix.
  • proxy_pass to a named upstream with no scheme — pointing proxy_pass backend; (or via a variable) at an upstream whose members lack ports leaves nothing to default from.
  • DNS name without a portserver 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 (where http:// would default to 80) reused verbatim under stream, 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 — every server entry needs ip:port, always.
  • Prefer explicit ports even in http upstreams; relying on the proxy_pass scheme 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 http proxy to stream: identical-looking server lines that worked before now need explicit ports.

See the NGINX category for more guides.

Free download · 368-page PDF

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?

Free download · 368-page PDF

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.