497 HTTP Request Sent to HTTPS Port
Plain HTTP traffic arriving on the HTTPS port triggers the 497 HTTP Request Sent to HTTPS Port status code in nginx.
Usage
The 497 HTTP Request Sent to HTTPS Port status code indicates the HTTP request is valid, but the server refuses to process because the request was sent in plain text to the HTTPS port. Resolving this error requires either sending the request as HTTPS to the same port, or sending the plain HTTP request to the correct HTTP port.
Example
A client sends a plain HTTP request to port 443, which expects HTTPS traffic. The nginx server records the failure as 497 HTTP Request Sent to HTTPS Port and, in the default configuration, answers the client with a 400 response carrying the built-in error page.
Request
GET /login HTTP/1.1
Host: www.example.re
Response
HTTP/1.1 400 Bad Request
Server: nginx
Content-Type: text/html
Connection: close
<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>
<hr><center>nginx</center>
</body>
</html>
Redirecting instead of erroring
The error_page directive catches 497 and converts
the failed plaintext request into a redirect toward
the encrypted address.
server {
listen 443 ssl;
server_name example.re;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
error_page 497 https://$host$request_uri;
}
Two details decide whether the result matches the intent.
The emitted status is 302 rather than 301.
nginx sends a temporary redirect for any error_page
target outside the redirect range, and 497 carries an
implicit rewrite to 400. Stating the code
explicitly produces a permanent redirect instead.
error_page 497 =301 https://$host$request_uri;
Placement matters as well. The condition is detected
before nginx selects a location, so an error_page
line inside a location block never runs. The
directive belongs at server or http level.
The redirect is a fallback rather than the primary answer. A plaintext listener answering on port 80 handles the same traffic without an error path, and costs nothing.
server {
listen 80;
server_name example.re;
return 301 https://$host$request_uri;
}
How to fix
The most direct fix uses the nginx
error_page 497 directive to automatically
redirect plain HTTP requests arriving
on the
HTTPS port to the correct protocol:
server {
listen 443 ssl;
server_name www.example.re;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
error_page 497 =301
https://$host:$server_port$request_uri;
}
This catches the 497 internally and sends a 301 redirect to the client, preserving the original port number and request URI.
For standard port 443, a separate server block
listening on port 80 handles the common case of
users typing http:// in the browser:
server {
listen 80;
server_name www.example.re;
return 301 https://$host$request_uri;
}
Update hard-coded http:// URLs in the
application codebase. Configuration files,
environment variables, database records, and
API endpoint definitions referencing http://
cause clients to connect on the wrong protocol
repeatedly.
Ensure the application generates HTTPS URLs for all links, form actions, and redirects. Relative URLs avoid protocol mismatches entirely.
Check upstream proxy or load balancer settings. A reverse proxy terminating TLS and forwarding plain HTTP to nginx on port 443 triggers this error if nginx expects TLS on the same port. Configure the upstream to forward using the same protocol nginx expects.
See also
- 400
- Google: HTTP status codes and network errors
- 301
- nginx ssl_module Error Processing
- HTTP status codes