How HTTP Works
4xx · Client errorNon-standard · nginx
< HTTP/1.1 497 HTTP Request Sent to HTTPS Port

497 HTTP Request Sent to HTTPS Port (nginx)

nginx 497 means plain HTTP hit an HTTPS port; clients see "400 The plain HTTP request was sent to HTTPS port". Fix with error_page 497. Also 494, 495, 496.

Reviewed 3 min readintermediate5 sourcesTry itMarkdown
Cacheable
No
Retry?
No: use https:// or redirect with error_page 497
Usually sent by
nginx (sent to the client as 400)
Spec
nginx ssl module docs
Often confused with
400
On this page

TL;DR: 497 is nginx’s internal code for “a plain HTTP request arrived on a TLS port”. The client sees 400 Bad Request with the body “The plain HTTP request was sent to HTTPS port”. Use https:// or add error_page 497 =301 https://$host:$server_port$request_uri; to redirect.

What it means

When a listen ... ssl socket receives bytes that are not a TLS handshake, nginx has already parsed them as an HTTP request. If the connection has no TLS, the request is finalized with its internal NGX_HTTP_TO_HTTPS code, 497. The nginx source comment says the code exists to tell this case apart from an ordinary 4xx during error-page redirection. By default the response uses a 400 status line and this body (from ngx_http_special_response.c):

HTTP/1.1 400 Bad Request
Server: nginx

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>

Because the status is 400, you search the web for that sentence, not for 497. The nginx docs describe it as “a regular request has been sent to the HTTPS port”. The error log, at info level, records client sent plain HTTP request to HTTPS port.

Who sent it?

An nginx whose listening socket has TLS enabled. The page is nginx’s own (with its Server: nginx header), even when the request reached it through a proxy. A common trap: nginx A proxies to nginx B with proxy_pass http://b:443;. The 400 text then comes from B, and A passes it on.

Fix it

  1. Use the right scheme. http://example.com:443/ produces this error; https://example.com/ does not. Check bookmarks, hard-coded URLs, health checks and webhooks configured with http:// and port 443.

  2. Fix the proxy hop. If nginx proxies to a TLS backend:

    location / {
        proxy_pass https://backend.internal:443;
        proxy_set_header Host $host;
    }

    With proxy_pass http://backend.internal:443; the backend receives plaintext on its TLS port. In Kubernetes ingress-nginx, the matching annotation is nginx.ingress.kubernetes.io/backend-protocol: "HTTPS".

  3. Redirect instead of failing. If you deliberately serve HTTPS on a non-standard port and people type http://:

    server {
        listen 8443 ssl;
        server_name example.com;
        error_page 497 =301 https://$host:$server_port$request_uri;
    }

    The nginx docs note the redirect happens after the request is fully parsed, so $request_uri, $uri and $args are available. For ports 80 and 443 use a separate listen 80 block that returns 301 and add HSTS.

  4. Load balancers and health checks. Make sure the backend protocol matches what the port speaks. A health check or backend configured for HTTP and pointed at an HTTPS port gets exactly this 400 response.

  5. Redirect loops. If you add the 497 redirect and the browser reports too many redirects, a proxy in front is likely stripping TLS; see ERR_TOO_MANY_REDIRECTS.

Reproduce

curl -i http://example.com:443/

A plain-HTTP request to a TLS port returns the 400 page above. Compare with curl -I https://example.com/ for the working case.

494, 495 and 496

The same block of nginx-internal codes (NGX_HTTP_NGINX_CODES, starting at 494) contains three siblings. Defaults send a 400 status to the client for each, with a distinct message in the body, and each can be matched by error_page:

CodeBody text nginx sendsWhen
494Request Header Or Cookie Too LargeA request header line or the header block exceeds client_header_buffer_size and large_client_header_buffers (default 4 buffers of 8k). Oversized cookies are the usual cause.
495The SSL certificate errorClient certificate verification failed with ssl_verify_client on or optional.
496No required SSL certificate was sentssl_verify_client on and the client presented no certificate.

For 494, nginx answers 400 where RFC 6585 would suggest 431. Fix it by shrinking cookies or raising large_client_header_buffers 4 16k;. For 495 and 496, a custom page can explain the problem to users:

error_page 495 496 /client-cert-error.html;

nginx documents 495, 496 and 497 in the ssl module; 494 appears in the source and in the large-header handling, not in that list.

Frequently asked questions

What does "400 The plain HTTP request was sent to HTTPS port" mean?

A client spoke plain HTTP to a port where nginx expects TLS. nginx recognises that, finalizes the request with its internal code 497, and sends a 400 Bad Request page by default. The fix is to use https:// in the URL or to redirect, not to change the server certificate.

Is 497 an official HTTP status code?

No. It is one of the internal codes nginx defines (494 to 497), defined in the source so that error_page can match these conditions separately from an ordinary 400. By default the client receives a 400 status, not 497.

How do I redirect HTTP to HTTPS on the same port with nginx?

Add error_page 497 =301 https://$host:$server_port$request_uri; to the TLS server block. nginx then answers a plain HTTP request on that port with a redirect to the HTTPS URL. A dedicated listen 80 server block that returns 301 is the cleaner solution for the standard ports.

Why does my proxy_pass to an HTTPS backend return this error?

Because proxy_pass uses http:// while the backend port speaks TLS. Use proxy_pass https://backend:443; so nginx opens a TLS connection. The same message can also come from a load balancer or health check configured to send HTTP to the HTTPS port.

What are nginx 494, 495 and 496?

494 is a request header or cookie too large for the configured buffers. 495 is a client certificate verification error and 496 means no required client certificate was presented. Like 497 they are nginx-internal codes that reach the client as 400 Bad Request unless you map them with error_page.

Sources

  1. nginx: ngx_http_ssl_module (error codes 495, 496, 497)nginx.org
  2. nginx: error_page directivenginx.org
  3. nginx: large_client_header_buffersnginx.org
  4. nginx source: ngx_http_request.h (internal status codes)github.com
  5. RFC 9110: HTTP Semantics, Status Codesrfc-editor.org

Keep going

Browse /search