A subdomain reaches the parent domain when NGINX selects the wrong virtual server or when a redirect rule—inside NGINX or in the proxied application—sends the parent hostname in its Location header. The reliable fix is to declare the subdomain explicitly on every listener it uses, isolate intentional canonical redirects in their own server blocks, and identify the component that generated the redirect before changing configuration.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
HTTP and HTTPS are separate NGINX listener contexts. A configuration that works for http://app.example.com can still send https://app.example.com elsewhere if the TLS server block, certificate, or server_name is incomplete.
As an Amazon Associate I earn from qualifying purchases.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How NGINX decides which server block handles a subdomain
NGINX uses the request’s Host header and the address and port that accepted the connection to choose a virtual server. The server_name directive supports exact names, wildcards, and regular expressions. Matching follows NGINX’s priority rules and stops at the first matching variant, so a broad wildcard or an unintended default can win when an exact subdomain declaration is missing or conflicts with another block.
The exact name must exist on the listener that received the request
For an HTTP request, NGINX evaluates the blocks listening on port 80. For HTTPS, it evaluates the TLS blocks on port 443, while also using the TLS configuration and certificate presented during the handshake. Declaring app.example.com only in a port-80 block does not make it a match on port 443.
#1 Best Overall
What happens when no name matches
Every address-and-port combination has a default server. The NGINX administration guide states: “If the Host header field does not match a server name, NGINX Plus routes the request to the default server for the port on which the request arrived.” If that default block serves the parent domain or contains a catch-all redirect, the browser appears to have been “stolen” by the main site.
Common causes include a misspelled subdomain, a hostname present in another file but not the active configuration, a wildcard such as *.example.com, duplicate declarations, or a server_name _; catch-all that became the default.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Identify who emits the redirect before editing anything
Look at the response headers rather than inferring the cause from the final browser URL. Run both protocols so you can compare listener behavior:
curl -I http://app.example.com/path
curl -Ik https://app.example.com/path
Record the status code and the complete Location value. A 301 or 302 whose location names the parent domain may be produced by NGINX, an upstream application, or another proxy in front of NGINX. A redirect that appears only on HTTPS points toward the TLS listener, certificate-host setup, or an HTTPS-only application rule.
Rank #2
| Observed evidence | Likely source | What to inspect |
|---|---|---|
| The request lands in a parent-domain or catch-all block | NGINX virtual-server selection | Exact server_name, default_server, wildcard names, and listener ports |
A matching block contains return 301 or a broad rewrite |
Intentional or accidental NGINX redirect | Server and location contexts, included snippets, and rule order |
The upstream response includes Location: https://example.com/... |
Proxied application or another upstream proxy | Application canonical URL/base URL and proxy redirect policy |
| NGINX-generated absolute redirects expose the parent name | Selected block’s primary name | server_name_in_redirect and the first name in server_name |
Declare the subdomain explicitly for HTTP
A destination block should contain the exact subdomain and should not also perform a parent-domain redirect. A minimal HTTP proxy configuration is:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
}
}
If the request’s Host is app.example.com and this block is active on the address receiving port 80 traffic, NGINX can select it instead of the parent site’s default block. Keep the hostname spelling identical to the DNS name clients use.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Configure HTTPS as a separate virtual server
Repeat the exact hostname in the TLS block and provide a certificate that covers it:
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://app_backend;
}
}
The HTTP and HTTPS blocks can proxy to the same backend, but they are still independent matches. Verify that the 443 block is loaded on the address clients reach, that its certificate includes the subdomain, and that no other 443 block with a broader name or default_server takes precedence.
Rank #3
Keep deliberate hostname redirects in their own block
When an old hostname really should move to another hostname, use a dedicated server block:
server {
listen 80;
server_name old.example.com;
return 301 https://example.com$request_uri;
}
NGINX’s rewrite-conversion guidance calls the separate-server approach “the right way” for this pattern and describes an if-based alternative as “wrong, cumbersome, and ineffective.” The return directive can issue 301, 302, 303, and 307 responses in server or location context. For a straightforward hostname canonicalization, return is clearer than a broad rewrite.
Do not place that return in the block intended to serve app.example.com. Also inspect distribution-provided include files and snippets: a redirect inherited from an include can be invisible in the file you edited. A default_server catch-all that returns the parent URL is another frequent source of the symptom.
Inspect the merged configuration, not just one file
NGINX may load several files, so inspect the complete effective configuration:
Rank #4
sudo nginx -T
Search the output for every item that can affect selection or redirection:
listen 80 default_server;andlisten 443 ssl default_server;server_name _;catch-alls and wildcard names such as*.example.com- Every exact
app.example.comdeclaration, including declarations in included files - Parent-domain
return 301orreturn 302directives rewritedirectives that construct a parent-domain URL- Duplicate or conflicting
server_nameentries - Include ordering that places an unintended block before the intended virtual server
After changing a file, validate and reload the running configuration:
Recommended Free Tools
sudo nginx -t && sudo nginx -s reload
A successful syntax test confirms that NGINX accepted the configuration; it does not by itself prove that DNS, the listener address, the certificate, or the selected server block is correct.
When the upstream application creates the parent-domain URL
NGINX can select the correct subdomain block and still pass through a redirect generated by the application behind proxy_pass. In that case the upstream response contains a Location header naming the parent domain. Typical causes are an application canonical URL, base URL, trusted-host setting, or scheme detection that does not know the public hostname.
Best Value
Confirm the upstream headers in the access or proxy logs and compare them with the response seen by curl. Correct the application’s canonical URL/base URL or adjust the proxy’s redirect handling so that the public subdomain is preserved. Do not assume that a visible parent-domain URL proves NGINX authored the redirect.
Rewrite processing can create a second redirect
Server-context rewrites run once before NGINX selects a location. A rewrite using the last flag starts a new location search; break stops rewrite processing in the current context. Overlapping rules can therefore apply another rule on the second search, produce an unexpected hostname, or create a redirect cycle.
Free tools Windows power users keep installed
One-click scans. No signup required.
Keep host canonicalization in one dedicated server block. Use a direct return when the destination can be built from standard variables such as $request_uri, and narrow path rewrites so they cannot match every hostname.
Why an NGINX-generated absolute redirect may show the parent name
The server_name_in_redirect setting controls whether absolute redirects generated by NGINX itself use the primary name from the selected server_name directive. This can matter for automatic redirects such as one that adds a trailing slash. If the selected block lists the parent domain as its primary name, NGINX may expose that name even though the request arrived through another hostname.
First verify which block was selected and what names it declares. Change this setting only after confirming that it is the source; changing it globally can alter redirects for unrelated virtual servers.
Quick Recap
A complete repair workflow
- Verify DNS and the endpoint. Confirm that the subdomain resolves to the intended NGINX instance and that both HTTP and HTTPS reach that instance rather than different front ends.
- Capture the redirect. Run
curl -I http://app.example.com/pathandcurl -Ik https://app.example.com/path. Save the status and exactLocationheader. - Separate NGINX from the upstream. Use response headers and logs to determine whether the parent URL was emitted by NGINX or returned by the proxied application.
- Dump the active configuration. Run
sudo nginx -Tand inspect defaults, catch-alls, wildcards, duplicate names, redirects, rewrites, and includes for both ports. - Make matching explicit. Add
app.example.comto the exact HTTP and TLSserver_namedirectives, and ensure the TLS block has a certificate covering that name. - Remove the conflicting rule. Move a deliberate parent-domain redirect into a server block for the old hostname, or narrow an accidental
return/rewriteso it cannot match the subdomain. - Validate, reload, and retest. Run
sudo nginx -t && sudo nginx -s reload, then repeat bothcurlrequests. If the redirect remains, fix the upstream canonical URL or proxy policy. - Rule out client caching. Browsers cache permanent 301 responses. Test with
curlor a clean client after the server is corrected before concluding that the old redirect is still active.
Choosing the right fix
| Where the redirect is generated | Most precise fix | Why it works |
|---|---|---|
| Wrong NGINX virtual server | Add the exact subdomain to the matching HTTP or HTTPS block and correct defaults | Host selection becomes deterministic on the listener that received the request |
| Intentional NGINX hostname redirect | Use a separate old-host server block with return 301 |
The redirect applies only to the hostname being retired |
| Broad rewrite or included snippet | Remove it from the destination block or narrow its host/path match | Unrelated subdomains no longer enter the rule |
| Upstream application | Correct the application’s canonical URL/base URL or proxy redirect policy | The backend emits the public subdomain instead of the parent domain |
| NGINX absolute redirect naming | Verify the selected block’s primary name and server_name_in_redirect |
NGINX-generated absolute URLs use the intended hostname |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




