October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

Nginx Reverse Proxy 502 Bad Gateway Only on HTTPS: How to Fix It

An HTTPS-only NGINX 502 usually comes from the 443 configuration or the TLS hop to the upstream. This guide shows how to isolate each hop, read error-log signatures, correct proxy protocol, configure trust and SNI, and verify the repair.
Length11 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If your NGINX reverse proxy works over HTTP but returns 502 Bad Gateway over HTTPS, the problem is usually in the HTTPS virtual host or in NGINX’s TLS connection to the upstream—not in the browser’s certificate alone. Check the active listen 443 ssl server block, confirm that proxy_pass uses the upstream’s real protocol and port, then use the error log to identify certificate, SNI, connection, or response-header failures.

What an HTTPS-only 502 means

HTTP status 502 Bad Gateway means a server acting as a gateway or proxy received an invalid response from its upstream server. NGINX can return 502 when it cannot complete the upstream TLS handshake, connects to the wrong service, or receives a connection that closes before valid HTTP response headers arrive. A request that receives no upstream response before a gateway timeout is generally closer to 504 Gateway Timeout semantics.

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.

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

When the same URL succeeds over HTTP and fails over HTTPS, do not assume that only encryption was added. NGINX may be selecting a different server block, location, upstream name, port, headers, path rewrite, client-certificate policy, or timeout for port 443. HTTPS also introduces a second possible TLS connection:

  • Hop 1: the browser or API client connects to NGINX over HTTPS.
  • Hop 2: NGINX connects to the upstream over either clear-text HTTP or HTTPS, depending on proxy_pass.

A valid public certificate on the NGINX listener proves only that the first hop can be established. It does not prove that NGINX trusts the upstream certificate, sends the expected SNI name, or is even using the correct upstream protocol.

Start by separating the two connections

Run tests from the NGINX host, not only from your workstation. This avoids confusing a client-to-NGINX problem with an NGINX-to-application problem.

  1. Test the upstream directly. For an HTTPS backend, run curl -vk https://backend.example.com/health. For a clear-text listener, use curl -v http://127.0.0.1:8080/health. A direct failure indicates reachability, service, or upstream TLS trouble independent of the public listener.
  2. Inspect the upstream handshake when necessary. Run openssl s_client -connect backend.example.com:443 -servername backend.example.com. Check the selected certificate, issuer chain, negotiated protocol, and whether the server completes the handshake.
  3. Test the public endpoint. Run curl -vk https://public.example.com/health and compare its result and timing with the direct upstream request.

If the direct upstream request fails, fix the backend listener, firewall, certificate, or service name first. If it succeeds but the public HTTPS request fails, concentrate on the loaded 443 configuration and NGINX’s proxy settings.

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

Inspect the configuration NGINX is actually using

Files on disk are not necessarily the configuration in the running process. Included files, duplicate server_name entries, and a missing reload can leave NGINX serving a different block from the one you edited.

  1. Run nginx -t. This checks syntax and reports whether the configuration test succeeds.
  2. Run nginx -T. This prints the complete expanded configuration, including files loaded with include. Search the output for listen 443 ssl, the public server_name, and the relevant location.
  3. After correcting the file, reload NGINX through your service manager and reproduce one request while watching the error log. A syntax test alone does not apply a change to an already running worker process.

Compare the working HTTP block with the failing HTTPS block line by line. Verify the certificate and key paths, server_name, selected location, proxy_pass URL, upstream port, path handling, and every proxy_set_header and proxy_ssl_* directive. NGINX reverse proxies a request by sending it to the configured proxy server, fetching the response, and returning that response to the client. A difference in any of those stages can affect only HTTPS.

Match the upstream scheme and port

The most common configuration error is treating “the public site uses HTTPS” as proof that the backend must also use HTTPS. The two protocols are independent.

Clear-text HTTP upstream

If the application listens for ordinary HTTP on port 8080, terminate TLS at NGINX and proxy internally with an HTTP URL:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
server {
    listen 443 ssl;
    server_name app.example.com;
    ssl_certificate     /etc/ssl/app/fullchain.pem;
    ssl_certificate_key /etc/ssl/app/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

The browser-to-NGINX hop is encrypted; the local hop is clear-text HTTP. That is valid when the backend is intentionally bound to HTTP and the network between NGINX and the service is trusted.

HTTPS upstream

Use an HTTPS scheme only when the selected upstream port actually speaks TLS:

location / {
    proxy_pass https://api.example.com;
    proxy_ssl_server_name on;
    proxy_ssl_name api.example.com;
    proxy_ssl_trusted_certificate /etc/nginx/ca/upstream-ca.pem;
    proxy_ssl_verify on;
    proxy_set_header Host api.example.com;
}

Using https:// against a clear-text HTTP port commonly produces a TLS error and then a 502. Using http:// against a TLS-only port fails before NGINX can receive an HTTP response. Confirm the backend’s listening protocol from its service configuration and with a direct curl test; do not infer it from the public URL.

Fix upstream certificate trust and hostname validation

When NGINX connects to an HTTPS upstream, it may need to validate the certificate chain and identity. Publicly trusted certificates usually work without extra CA configuration. Private PKI and self-signed deployments require the CA certificate that issued the upstream certificate.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • proxy_ssl_trusted_certificate points NGINX at the trusted CA file for the upstream.
  • proxy_ssl_verify on enables certificate verification; keep verification enabled unless you have a documented, temporary exception.
  • proxy_ssl_name sets the TLS name used for certificate identity checks and SNI when explicitly configured.
  • proxy_ssl_server_name on sends the upstream hostname through TLS SNI.

A frequent failure occurs when proxy_pass targets an IP address while the certificate is issued to a DNS name such as api.example.com. The server may also use SNI to select the correct certificate or virtual host. Target the service hostname, set the TLS name when needed, and keep the HTTP Host header aligned with the application’s expected virtual host.

Do not make disabling verification your first fix. It can hide an incorrect hostname, an incomplete chain, or a man-in-the-middle risk. If verification is intentionally disabled for a controlled internal service, document the reason, scope, and compensating network controls.

Use the error log to identify the failing layer

Reproduce one failing HTTPS request while reading the NGINX error log. Capture the exact line, including the upstream address and port, before changing settings. The wording normally tells you which branch to investigate.

Log signature What it usually indicates Next check
SSL_do_handshake() failed TLS negotiation, protocol, certificate, or SNI failure between NGINX and the upstream Test with openssl s_client; verify scheme, hostname, SNI, supported protocols, and trust settings
certificate verify failed NGINX cannot validate the issuer chain or certificate identity Install the correct private CA, check the chain, and use the certificate’s DNS name
wrong version number NGINX is probably speaking TLS to a clear-text HTTP service, or using the wrong port Change https:// to http:// when appropriate and confirm the listener
connect() failed (111: Connection refused) No process is listening at the selected address and port, or a firewall is actively rejecting the connection Check service status, bind address, container port mapping, security groups, and host firewall rules
upstream prematurely closed connection The upstream closed the socket before sending valid response headers Inspect application logs, protocol expectations, request size, and upstream keepalive behavior
upstream timed out The upstream did not respond within the configured timeout Investigate latency, overloaded workers, network filtering, and timeout values; a true no-response case is closer to 504 semantics

The status code alone is not enough to choose a fix. A valid application response with a 4xx or 5xx status is still an HTTP response and should normally be passed through by NGINX. A gateway 502 means NGINX could not obtain a valid upstream response in the first place.

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

Compare HTTP and HTTPS deliberately

Do not assume the two listeners inherit identical behavior. Make a short diff of the effective configuration printed by nginx -T and check these items:

  • Listener and name selection: Is the request reaching the intended listen 443 ssl block and matching server_name?
  • Proxy scheme and port: Does HTTPS use the same upstream endpoint as HTTP, or is that difference intentional?
  • Upstream hostname: Is the 443 block using an IP, an internal DNS name, or a different upstream group?
  • Headers: Does it set Host, X-Forwarded-Proto, X-Real-IP, or connection headers differently?
  • TLS directives: Are proxy_ssl_server_name, proxy_ssl_name, trusted CA, client certificate, and verification settings present where required?
  • Path rewriting: Does a trailing slash or a different location change the URI sent to the application?
  • Timeouts and buffering: Did the HTTPS location override proxy_connect_timeout, proxy_read_timeout, or response buffering?

NGINX supports both HTTP and HTTPS in proxy_pass. The certificate used by the client-facing listener is configured separately through the SSL module, so a correct listener certificate does not compensate for a broken upstream definition.

Check headers, virtual hosts, and path handling

Even after the TLS handshake succeeds, an upstream can close the connection if it receives an unexpected host, protocol indicator, or URI. NGINX changes the proxied Host and Connection headers by default unless you override them. Applications that route by virtual host may therefore behave differently through the HTTPS block.

Set the headers required by the application explicitly, and use a consistent forwarded-protocol value:

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.
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;

For an upstream that expects a specific host rather than the public host, set that exact name instead, as in proxy_set_header Host api.example.com;. Do not change the header blindly: the correct value depends on the backend’s virtual-host configuration.

Review trailing slashes in proxy_pass. A URI component in the directive can replace the matching part of the request path, while a directive without one forwards the path differently. If HTTP and HTTPS select different locations, the application may see different endpoints and terminate the connection before returning headers.

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

Network and service checks

A 502 can be caused by a perfectly valid NGINX configuration pointing at an unreachable service. Check the complete path from the NGINX host to the upstream:

  • Confirm the application process is running and listening on the expected address and port.
  • Check whether it binds only to 127.0.0.1, an internal interface, or an address unavailable from NGINX.
  • For containers, verify the network name, published port, and container health state rather than assuming the host port equals the container port.
  • Review host firewalls, cloud security groups, network ACLs, and service-mesh policies.
  • Resolve the upstream hostname from the NGINX host and verify that DNS is not returning an unintended address.

When the log shows connection refusal, increasing proxy timeouts will not help; there is no listener to wait for. When the log shows a handshake error, opening a firewall port alone will not fix the certificate or protocol mismatch.

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

A repeatable recovery procedure

  1. Record the symptom. Note the exact HTTPS URL, status, timestamp, and whether HTTP succeeds for the same path.
  2. Run the direct upstream test. Use the correct curl scheme and, for TLS, test SNI with openssl s_client.
  3. Validate syntax and dump effective configuration. Run nginx -t, then nginx -T; identify the selected 443 server and location.
  4. Correct the protocol and port. Use http:// for a clear-text backend and https:// only for a TLS listener.
  5. Correct identity and trust. Use the upstream DNS name, enable SNI when required, install the private CA, and keep verification enabled.
  6. Align headers and URI behavior. Set the expected Host, forwarded-protocol headers, and path rules.
  7. Reload and reproduce once. Confirm the new configuration is loaded, then read the corresponding error-log line.
  8. Check the application logs. If NGINX now connects but the upstream closes early, the remaining fault is usually in application protocol handling, request limits, or worker health.

Make one logical change at a time. Changing the scheme, disabling verification, increasing timeouts, and rewriting headers simultaneously makes the original failure difficult to identify and can leave an insecure configuration behind.

Common fixes and their trade-offs

Failure category Appropriate fix What not to do
Wrong upstream protocol Match proxy_pass scheme and port to the backend listener Do not force HTTPS onto a clear-text port or HTTP onto a TLS-only port
Private or self-signed CA Provide the issuing CA with proxy_ssl_trusted_certificate and verify the chain Do not permanently disable verification just to make the 502 disappear
Hostname or SNI mismatch Use the certificate’s service name, enable proxy_ssl_server_name, and set proxy_ssl_name as needed Do not substitute an IP address when the service selects certificates by hostname
Connection refusal Start or rebind the service, correct the port, or repair firewall and container networking Do not increase read timeouts for a port with no listener
Early upstream close Inspect application logs, request headers, URI rewriting, protocol expectations, and worker limits Do not treat an application crash as a certificate problem without checking logs
Slow or absent response Measure latency and adjust timeouts only after reachability and service health are confirmed Do not call every timeout a 502; a genuine no-response condition generally maps to 504 behavior

When the 502 is not an NGINX configuration error

Once the direct upstream request, TLS handshake, and effective proxy configuration all succeed, inspect the application itself. A backend can accept TCP and TLS, then close the connection because it expects a different application protocol, rejects a required header, exceeds a request-size limit, runs out of workers, or crashes while processing the request. The NGINX error log may report only “upstream prematurely closed connection”; the application log supplies the cause.

Likewise, a service that returns a normal HTTP 500 or 404 is not producing a gateway 502. Preserve that origin response while troubleshooting rather than replacing it with a generic gateway error. This distinction tells you whether to work on proxy transport or application behavior.

Final verification checklist

  • The failing request reaches the intended listen 443 ssl and server_name block.
  • nginx -t succeeds and the running process has been reloaded.
  • The upstream scheme and port match the service’s actual listener.
  • A direct request from the NGINX host succeeds using the same hostname and protocol.
  • Upstream certificate trust, hostname validation, and SNI are configured for the deployment.
  • The HTTP Host header and forwarded-protocol headers match application requirements.
  • Firewall, DNS, container, and bind-address checks show a reachable listener.
  • The error-log signature no longer indicates handshake failure, refusal, or premature closure.
  • Only then are timeout changes considered, based on measured response latency.

Conclusion

An HTTPS-only NGINX 502 is usually a mismatch between the active 443 configuration and the upstream service: wrong scheme or port, untrusted certificate, missing SNI, incorrect hostname, unreachable listener, or an upstream that closes before sending HTTP headers. Separate the client and upstream hops, inspect the effective configuration with nginx -T, test the backend directly, and let the exact error-log signature determine the fix. A valid certificate on the public listener is necessary for the first hop, but it says nothing about whether NGINX can securely and correctly reach the backend.

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

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.