Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

When NGINX shows another site, the request usually reached a different server block than you expected. NGINX first selects a listening address and port, then matches the request host against server_name. If no name matches, it serves that port’s default server. HTTPS adds a TLS Server Name Indication (SNI) decision before the HTTP Host header is processed, so port 80 can be correct while port 443 serves the wrong certificate or website.

The reliable fix is to verify DNS, inspect the complete configuration NGINX actually loaded, correct the HTTP and HTTPS blocks separately, remove unintended defaults or wildcards, then test with the intended Host and SNI names.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How NGINX decides which website to serve

A domain name does not select a website by itself. NGINX makes a sequence of decisions for every connection.

1. It selects a listening socket

The destination IP address and port are considered first. A block listening on listen 80 cannot answer a request that arrived on port 443, and a block bound only to one address will not receive traffic sent to another address on the same server. IPv4 and IPv6 can therefore select different blocks if their listen directives are not configured consistently.

2. It compares the host name

After choosing the address and port, NGINX compares the HTTP Host value with the server_name directives available on that socket. The matching order is:

  1. an exact name, such as example.com;
  2. the longest wildcard beginning with an asterisk, such as *.example.com;
  3. the longest wildcard ending with an asterisk, such as mail.*;
  4. the first regular-expression name in configuration order.

A broad wildcard can therefore win over a block you thought would handle the request, while a duplicate or conflicting name can leave one block ignored.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. It falls back to a default server

If the Host value does not match any name, NGINX uses the default server for that port. Unless a listen directive includes default_server, the first server listed for that address and port is the default. The default_server flag belongs to listen, not to server_name; adding _ as a name does not, by itself, create a catch-all.

As the NGINX documentation puts it: “If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port.”

4. HTTPS performs an earlier SNI selection

For HTTPS, the client normally sends the requested name as SNI during the TLS handshake. NGINX can select a TLS server context and certificate from that value before it sees the HTTP request and its Host header. If the 443 configuration, certificate names, or SNI handling is wrong, the browser may show another certificate or site even though the HTTP block on port 80 is correct.

What the symptom usually means

Symptom Likely selection problem First check
NGINX welcome page on HTTP The request is reaching the distribution’s first or explicit default server, or your domain is pointed at the wrong machine. Check DNS, then inspect every listen 80 block in the loaded configuration.
Another customer’s or project’s site appears The Host name is unmatched, duplicated, captured by a wildcard, or sent to a shared proxy with a different origin. Send an explicit Host header to the origin and review all matching server_name values.
HTTP is correct but HTTPS is wrong The 443 block is missing or mismatched, SNI selects another block, or the certificate and content are configured in different blocks. Test with SNI and inspect every listen 443 ssl block.
Bare domain works but www does not Only one of the two names is in server_name, or DNS for the names points to different addresses. Check A/AAAA records and include both names in the intended blocks.
Only some networks see the wrong site Different DNS answers, an IPv6 path, a CDN or reverse proxy, or cached DNS is involved. Compare A and AAAA results and test each address directly.

Step 1: Verify that DNS reaches the intended server

Do this before changing NGINX. A perfectly correct server block cannot affect a request that never reaches that server.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Query the domain’s IPv4 and IPv6 records:
dig +short A example.com
dig +short AAAA example.com

Replace example.com with the affected name. Compare the returned addresses with the public addresses of the NGINX host. Check the bare domain and www separately; they can legitimately have different records, but an accidental difference is a common cause of inconsistent results.

  1. If a reverse proxy, CDN, load balancer or hosting panel is in front of NGINX, determine whether the response comes from that layer or the origin. Look at response headers and the certificate, but do not assume a familiar Server header proves which machine answered.
  2. Test the origin directly when you know its address. This sends the correct host while bypassing public DNS:
curl -i -H 'Host: example.com' http://203.0.113.10/

For HTTPS, use --resolve so curl connects to the chosen address while still sending the requested host and SNI:

curl -vk --resolve example.com:443:203.0.113.10 https://example.com/

If the direct-origin result is correct but the public URL is wrong, investigate DNS or the proxy/CDN rather than changing the local server block.

Step 2: Inspect the configuration NGINX actually loaded

Editing a file is not enough: NGINX may include a different file, load a site you forgot about, or ignore a block because of a conflict. Dump the complete active configuration:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo nginx -T

On systems where the binary uses a non-default configuration path, use the same -c option used by the service. Save or page through the output and locate every relevant server block. A quick search can reduce the noise:

sudo nginx -T 2>&1 | grep -nE '^[[:space:]]*(listen|server_name|include|root|proxy_pass)'

For the affected domain, record:

  • every listen 80 and listen 443 ssl line, including address-specific and IPv6 forms;
  • all server_name values, including wildcards and regular expressions;
  • which block contains the intended root, proxy_pass, redirects and certificate directives;
  • the files brought in by include statements;
  • any default_server flags and the order in which blocks appear.

Look for the same name declared in multiple blocks on the same address and port. During syntax testing, NGINX can warn that a conflicting server name is ignored; treat that warning as a routing defect, not harmless noise.

Step 3: Make the HTTP server block unambiguous

Include every required name

Put the bare domain and the required www name in the same intended block, or create an explicit redirect block for one of them. A basic site might look like this:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example;
    index index.html;
}

The names must match the actual request. A name such as www.example.com does not match example.com, and a typo or trailing dot can send a request to the fallback server.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Match the address that receives traffic

If the host has multiple addresses, an address-qualified directive such as listen 192.0.2.10:80 is not equivalent to a wildcard listener on another address. Ensure the block listens on the IPv4 and IPv6 addresses used by DNS, or deliberately remove the address that should not serve the site. Configure IPv6 explicitly with listen [::]:80 when the domain has an AAAA record.

Remove accidental defaults

Only one default server can apply to a particular address-and-port pair. Remove default_server from ordinary site blocks unless that is intentionally their role. If an old distribution welcome-site file is enabled first, it may become the default and display its page whenever the Host does not match.

Choose a deliberate unmatched-host policy

You can serve a neutral landing page, redirect unmatched names, return an error, or reject them. A minimal rejecting catch-all is:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name "";
    return 444;
}

Code 444 is an NGINX-specific behavior that closes the connection. If clients need a normal HTTP response, use a deliberate status such as 404 instead. Do not place a catch-all flag on every site; that creates a configuration conflict and obscures which block should answer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step 4: Configure HTTPS as a separate routing problem

Use the same host names on port 443

Port 80 and port 443 are separate listening sockets. The HTTPS block must name the domain and listen with SSL:

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/example;
    index index.html;
}

Use the paths and certificate-management method appropriate to your system. The certificate’s subject or Subject Alternative Name must cover every name clients use. A certificate for only the bare domain does not cover www unless www is included.

Test the certificate and SNI directly

Use curl to test both routing and certificate verification (the -k option is useful only while diagnosing a certificate mismatch):

curl -vk --resolve example.com:443:203.0.113.10 https://example.com/

To inspect the certificate selected during the handshake, request the SNI name explicitly:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
openssl s_client -connect 203.0.113.10:443 -servername example.com -showcerts

Check the returned certificate names and the HTTP body. If SNI returns a certificate for another domain, inspect the order and names of all 443 blocks, their default server, and any TLS-terminating proxy in front of NGINX.

Redirect HTTP only after HTTPS is correct

Once the 443 block works, you can make port 80 redirect to it:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

Keep the host names explicit. Do not use a broad wildcard redirect unless every captured subdomain is intended to resolve there.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common cases and their fixes

The NGINX welcome page appears

This normally means the request reached the default server rather than your named block. Confirm that DNS points to this host, verify that the request’s Host exactly matches your server_name, and inspect the loaded order of the port 80 blocks. Disable or repurpose the distribution’s welcome-site configuration only after confirming it is not needed for another name.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

HTTP works, but HTTPS shows another site

Do not assume the HTTP block controls HTTPS. Verify a dedicated 443 block, its server_name, certificate, address bindings and SNI behavior. Test with curl --resolve and openssl s_client -servername; these distinguish a wrong certificate selected during TLS from a later HTTP host-routing problem.

The bare domain and www disagree

Query A and AAAA records for both names. Then test each name with its own --resolve command. Add both names to the intended blocks or create an explicit, documented redirect from one canonical name to the other. Check both ports, because it is common to update one block and leave the other unchanged.

A wildcard captures the request

Review wildcard length and precedence. A wildcard beginning with * can capture many subdomains, and a regular expression can be selected according to configuration order. Replace broad patterns with exact names where possible. Narrow matching reduces the chance that a newly added site is silently routed to an existing one.

Only IPv6 users see the wrong site

An AAAA record can send browsers to IPv6 while your tests use IPv4. Compare curl -4 and curl -6, inspect the listen [::] blocks, and ensure the intended names and defaults exist on both address families. Correct or remove an obsolete AAAA record if the server is not ready to serve IPv6.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The origin is correct but public traffic is wrong

If an explicit origin test returns the expected site while the public hostname does not, NGINX is probably not the failing layer. Check the proxy or CDN’s origin address, host-header forwarding, TLS mode, cache and deployment state. Purge or bypass a cache only after confirming that the origin response is correct; caching cannot fix a request routed to the wrong origin.

Step 5: Validate, reload and retest

Use this order so a syntax error never replaces a working configuration with an untested one:

  1. Run the syntax and file-reference check:
sudo nginx -t

Resolve every error and warning about duplicate or conflicting names. Do not reload while the test fails.

  1. Reload the service without dropping existing connections:
sudo systemctl reload nginx

Use the service manager’s equivalent reload command if your distribution does not use systemd.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Test the intended HTTP name against the origin:
curl -i --resolve example.com:80:203.0.113.10 http://example.com/
  1. Test HTTPS with the same address override and inspect the certificate, status code, redirect target and response body:
curl -vk --resolve example.com:443:203.0.113.10 https://example.com/
  1. Repeat for www, IPv4 and IPv6 where applicable. A fix is incomplete if only one spelling or address family works.
  2. Retest through the real public DNS and any proxy after the origin tests pass. Compare response headers and certificate details to confirm that the public path reaches the corrected configuration.

When the match is still unclear: use targeted debug logging

NGINX’s debug logging can show virtual-host selection and other request details, but it is verbose and may require a build with debug support. Temporarily raise the relevant error_log level to debug, reproduce one request, and inspect the resulting log entries. Restrict this to a short diagnostic window, protect logs that may contain request data, and restore the normal level afterward. Configuration dumps and explicit Host/SNI tests should come first; debug logging is the escalation path when those do not reveal the selected block.

A configuration pattern that stays predictable

For a small deployment, keep one clearly named block for each protocol and make the fallback policy explicit. Use exact names for production sites, reserve wildcards for domains that genuinely share routing, and keep certificate directives with the HTTPS block that serves the corresponding content. Document which block is the deliberate default for each address and port, and remove obsolete site files instead of relying on their position in an include directory.

  • Every DNS name in use appears in the intended HTTP and HTTPS server_name directives.
  • The blocks listen on every address family that DNS advertises.
  • There is one intentional default per address-and-port pair.
  • No duplicate names or accidental regular expressions remain.
  • Certificates cover all requested names and are selected by the matching SNI block.
  • nginx -t passes before every reload.
  • Origin tests use explicit Host and SNI values, followed by tests through the public path.

The key distinction is between a file you edited and the configuration NGINX loaded. Once DNS, listening sockets, host matching, defaults and SNI are checked in that order, the “wrong site” response becomes a specific routing error that can be corrected rather than a mysterious browser problem.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.