Resolving Nginx 400 Error: "The plain HTTP request was sent to HTTPS port"

Nov 23, 2025 · Programming · 9 views · 7.8

Keywords: Nginx Configuration | SSL Error | HTTPS Redirection

Abstract: This article provides an in-depth analysis of the common Nginx 400 error "The plain HTTP request was sent to HTTPS port". Through comparison of erroneous and corrected configurations, it explains the mechanism of the default parameter in listen directives and offers complete configuration examples. The paper also discusses supplementary solutions like error page redirection, helping developers comprehensively understand and resolve such SSL/TLS configuration issues.

Problem Background Analysis

In Nginx server configuration, when attempting to handle both HTTP and HTTPS requests within the same server block, the 400 error "The plain HTTP request was sent to HTTPS port" frequently occurs. This error indicates that Nginx received an unencrypted HTTP request on an SSL port, while the server expects an encrypted HTTPS connection.

Erroneous Configuration Example

Below is a typical example of incorrect configuration:

server {
    listen 80;
    listen 443 ssl;
    server_name localhost;
    
    ssl on;
    ssl_certificate /opt/nginx/ssl_keys/ssl.crt;
    ssl_certificate_key /opt/nginx/ssl_keys/ssl.key;
    
    # Other configuration items...
}

With this configuration, when a client sends an HTTP request to port 443, Nginx rejects the request and returns a 400 error because SSL is explicitly enabled, but the request does not use the SSL protocol.

Detailed Solution

The correct solution involves using the default parameter in the listen directive:

server {
    listen 80;
    listen 443 default ssl;
    server_name localhost;
    
    # Important: Remove or comment out the ssl on directive
    # ssl on;
    
    ssl_certificate /opt/nginx/ssl_keys/ssl.crt;
    ssl_certificate_key /opt/nginx/ssl_keys/ssl.key;
    
    root /home/myhome/app/public;
    passenger_enabled on;
    
    # Other configurations remain unchanged...
}

The default parameter instructs Nginx to use this configuration as the default handler when no other server block matches. Combined with the ssl parameter, Nginx can intelligently decide whether to enable SSL encryption based on the connection type.

Technical Principles

The core of this solution lies in Nginx's connection handling mechanism:

  1. When using listen 443 default ssl, Nginx listens for all connections on port 443
  2. For actual SSL/TLS connections, Nginx automatically enables SSL processing
  3. For non-SSL connections, Nginx treats them as regular HTTP requests
  4. This avoids the "plain HTTP request sent to HTTPS port" error

In contrast, explicitly using the ssl on directive forces all connections to that port to use SSL, resulting in non-SSL requests being rejected.

Supplementary Solutions

In addition to the main solution, error page redirection can also be used:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl on;
    ssl_certificate /path/to/cert.crt;
    ssl_certificate_key /path/to/cert.key;
    
    # Use error code 497 to redirect HTTP requests to HTTPS
    error_page 497 https://$server_name:$server_port$request_uri;
}

Nginx defines the special error code 497 specifically for "HTTP request sent to HTTPS port" scenarios. By configuring error_page 497, such requests can be redirected to the correct HTTPS address.

Configuration Considerations

When implementing the solution, pay attention to the following points:

Conclusion

By properly configuring the parameters of Nginx's listen directive, the "plain HTTP request sent to HTTPS port" error can be effectively resolved. The main solution uses the default ssl parameter to enable Nginx's intelligent handling of connection types, while the error page redirection solution provides an alternative method for handling exceptional cases. Developers should choose the appropriate solution based on specific requirements to ensure the normal operation and security of web services.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.