# 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.

Source: https://howhttpworks.com/status-codes/497
Last reviewed: 2026-10-04

> **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`):

```text
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:

   ```nginx
   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://`:

   ```nginx
   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](https://howhttpworks.com/headers/strict-transport-security).
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](https://howhttpworks.com/debug/err-too-many-redirects).

## Reproduce

```bash
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`:

| Code | Body text nginx sends | When |
| --- | --- | --- |
| 494 | `Request Header Or Cookie Too Large` | A 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. |
| 495 | `The SSL certificate error` | Client certificate verification failed with `ssl_verify_client` on or optional. |
| 496 | `No required SSL certificate was sent` | `ssl_verify_client on` and the client presented no certificate. |

For 494, nginx answers 400 where RFC 6585 would suggest [431](https://howhttpworks.com/status-codes/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:

```nginx
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.
