497 HTTP Request Sent to HTTPS Port (nginx): Fix
497 HTTP Request Sent to HTTPS Port: nginx got plain HTTP on a TLS port. Fix in 3 checks — scheme, proxy, redirect. Free instant check, no sign-up.
Check your domain for this issue now
Free, no sign-up. Runs the exact check this guide describes and shows what to fix.
Problem
Requests to your site fail with 497 HTTP Request Sent to HTTPS Port, or the response body reads 400 Bad Request — The plain HTTP request was sent to HTTPS port. The number 497 shows up in your nginx access.log, in a proxy_pass error, or in a health-check dashboard.
Symptoms
- nginx logs a
497status, or returns a 400 whose body is literally “The plain HTTP request was sent to HTTPS port.” - The site works when you type
https://but breaks the moment something useshttp://against the same port. - A reverse proxy, load balancer, or ingress in front of nginx started returning 502/400 after a TLS change.
- A monitoring probe or health check on port 443 (or a custom port like 8443) reports failure while the browser is fine.
What This Error Actually Means
497 is nginx telling you the exact opposite of a certificate problem. TLS is configured. The listener has the ssl keyword, the certificate is loaded, the handshake would work — but the bytes that arrived weren’t a TLS handshake at all. They were a plaintext HTTP request: GET / HTTP/1.1\r\nHost: .... nginx reads the first bytes, sees an ASCII request line where it expected a TLS ClientHello, and refuses. Rather than emit a misleading TLS error, it raises its own code — 497 — and answers with a 400.
This is the reverse of SSL_ERROR_RX_RECORD_TOO_LONG. That error is a client speaking TLS to a port answering in cleartext. 497 is a client speaking cleartext to a port expecting TLS. In both cases someone got the scheme wrong; 497 just means nginx is the one that noticed, on the TLS side.
The important consequence: the fault is almost never in nginx’s TLS setup. It’s upstream of the ssl listener — a proxy forwarding http:// to an https:// backend, a health check pointed at the wrong scheme, or a person hitting http://host:443.
Top 3 Causes
- A reverse proxy or load balancer forwards plain HTTP to a TLS port — The most common cause in production. An upstream terminates TLS, then does
proxy_pass http://backend:443;to an nginx that listens withssl. The front-end sends cleartext to a port that demands TLS. The scheme inproxy_pass(or the target group protocol on an ALB) is wrong, not the certificate. - A health check or monitor uses the wrong scheme — An uptime probe, Kubernetes readiness check, or ELB health check is configured for HTTP on a port that only speaks HTTPS. The service is healthy; the probe is lying because it knocks in cleartext.
- A person or script hit
http://on an HTTPS-only port — A stale bookmark, a hardcodedhttp://link, a curl command withouthttps://, or a client pointed athttp://host:8443. Harmless individually, but noisy in logs and confusing when a script fails silently.
Diagnose with DechoNet
- SSL Check to confirm the port actually presents a valid certificate and completes a TLS handshake. If SSL Check succeeds, TLS is fine and the 497 is coming from a cleartext request in front of nginx — not from your certificate.
- Port Check to verify the port is open and reachable, so you can separate “wrong scheme” from “nothing listening.”
- HTTP Check against the
https://URL to confirm the app responds correctly over TLS, isolating the fault to whatever is sending plaintext.
Resolution Checklist
- Confirm the pattern: does
https://work whilehttp://on the same port fails? If yes, TLS is healthy and the problem is a cleartext request reaching the TLS listener. - Check every
proxy_passand upstream definition in front of this nginx. A TLS port must be addressed asproxy_pass https://...;, nothttp://...;. On an AWS ALB/NLB, set the target group protocol to HTTPS. - Check health-check and monitor configuration: a probe on 443 (or your TLS port) must use the HTTPS scheme, or it will trip 497 forever while the service is fine.
- For genuine client typos on an HTTPS-only port, add
error_page 497 =301 https://$host$request_uri;inside theserverblock to redirect stray plaintext requests. Do this only after ruling out a proxy misconfiguration — it will loop if the front-end is the one sending cleartext. - Run SSL Check to confirm the handshake completes; if it does, stop looking at the certificate and go fix the scheme upstream.
When to Escalate
- Escalate to whoever owns the load balancer or ingress if SSL Check shows a healthy certificate on the origin but 497s persist — the plaintext request is being generated between the edge and nginx, and the
proxy_passscheme or target-group protocol is the lever. - If 497 started right after a certificate install or a migration, suspect a front-end that was switched to talk to the new TLS port but is still configured to send
http://.
Related Tools
Related Guides
Share this guide