duplicate upstream
A duplicate upstream name prevents NGINX from loading the candidate HTTP configuration. This is a configuration-parser identity collision, not evidence of an unhealthy backend, DNS failure or two live servers fighting for a port. Preserve the named group, the reported source file/line and the actual include set; a failed candidate test does not show which configuration the running workers use. Match this output from nginx, then continue with sourced, read-only checks.
- Confidence
- high
- Platforms
- linux
- Verified
- 2026-10-01
Signature matched locally
duplicate upstreamOneLiners matches this pattern in your browser. Your pasted output is not stored or indexed.
What usually produces this signal
- Two explicit HTTP upstream definitions with the same name are loaded through one candidate include graph. Distinct source files can still collide; the reported second definition is not necessarily the first owner of that group.
- An include wildcard also selects a backup or generated copy. Renaming backend.conf to backend.backup.conf still matches *.conf, so keeping both files in that include directory can preserve the collision.
- The candidate comes from a different prefix, service argument, container volume or deployment generation than the reviewed configuration. A passed test on one path cannot establish that the intended service loads that same file set.
Collect evidence before changing the system
Reconcile the exact duplicate group with the selected include graph, not every configuration file
# Keep the original bounded error, named GROUP and file:line private.
# The owner compares the actual service/container binary, prefix and -c path.
# Inspect only the reported definition and its reviewed sibling/includes
# in a private editor; trace the specific include chain back to http.
# A basename ending .backup.conf STILL matches *.conf. Do not paste configs.
nginx -v
# Do not run a recursive secret-bearing config dump or nginx -T.Expected signal: The incident's candidate include graph contains both definitions of the named group, or exposes a different candidate/runtime path that needs reconciliation. A matching word in an unrelated file is not proof it is included; two server entries within one upstream are not duplicate group definitions.
Compare provenance and declaration boundaries, not a broad text count. The second diagnostic location helps locate the collision but does not authorize deleting that file, changing another tenant's group or renaming a group without reviewing proxy_pass references. Keep private endpoints, certificates and credentials out of shared evidence.
Test only an approved isolated candidate with explicit binary, prefix and configuration path
# OWNER-APPROVED staging snapshot only; review EVERY absolute include/log/
# pid/temp/certificate path first so this cannot touch a live prefix.
# Replace these placeholders with the actual approved installed binary/path.
# -t checks syntax AND attempts to open referenced files; not a pure read.
timeout 5s /usr/sbin/nginx -t -p /srv/approved-nginx-snapshot/ -c /srv/approved-nginx-snapshot/nginx.conf
# Preserve the exit status and exact failure locally; no -T or reload.Expected signal: A candidate containing the duplicate is rejected; the reviewed single-definition candidate passes its own configuration test. Preserve timeout or a different file-access/TLS/configuration error rather than treating every nonzero exit as this duplicate. The selected test may create/open logs in the approved isolated prefix.
A clean parser result does not contact the upstream, prove backend readiness, publish the candidate or identify the live workers' configuration. Our native control changed only the owned include selection; the Linux command here was not executed on a production service. Do not retry a failing live reload to obtain evidence.
Check the input against the result
Input and result
nginx: [emerg] duplicate upstream "fixture_backend" in <owned>/parts/backend.conf:1
# Executed native Windows NGINX 1.31.6 -t against an isolated owned prefix.
# Two owned .conf files declare fixture_backend; *.conf includes both.
# The control includes one file explicitly, leaving the other owned file intact.
# No HTTP listener, backend connection or production reload is involved.duplicate_test_exit=1
native_reason=duplicate upstream "fixture_backend"
owned_wildcard_definitions=2
explicit_single_include_exit=0
http_requests=0 production_reload=0The actual native parser rejected the two-definition candidate and accepted the same prefix with an explicit single include. The private Temp pathname was replaced with <owned> in the example, not used as a live path. The control demonstrates this include collision only; it does not prove a real service's loaded generation, upstream availability or successful publication.
Correct only the demonstrated cause
Have the configuration owner consolidate only the proven duplicate declaration or move an unwanted backup outside the actual include pattern, preserving its recoverable copy and reviewing all group references. Use the service's real binary/prefix/config identity for the approved candidate test. Publish/reload only through the owner's reviewed deployment and rollback procedure; do not delete all backups or rename unrelated groups.
Verify: The exact candidate has one intended declaration of the group, passes the approved configuration test, and the owner confirms the deployed generation and original safe route afterward. Backend readiness and running-worker adoption require separate evidence; a parser pass or an unchanged healthy old worker is not deployment success.
Stop if: The include graph or live prefix is unknown, private configuration ownership spans other tenants, absolute paths could touch production during the test, or removing/renaming the declaration would break references without a reviewed rollback.