NGINX Error: The plain HTTP request was sent to HTTPS port

Updated: January 20, 2024 By: Guest Contributor Post a comment

The Problem

Error messages can be intimidating, especially when you’re not sure where they’re coming from. ‘The plain HTTP request was sent to HTTPS port’ is a common NGINX error, which you might encounter when misconfiguring SSL settings or when redirects are not appropriately implemented.

Understanding why this error occurs is the key to fixing it. Essentially, the NGINX server expects a secure connection, but it’s receiving non-secure HTTP requests instead.

In this article, we’ll dive into some proven solutions to address this issue, ensuring that your NGINX server directs traffic correctly and keeps your data transmissions secure.

Solutions

Check NGINX Server Block Configuration

The server block (also known as a virtual host) in an NGINX configuration file must be correctly set up to handle SSL requests. If not correctly configured, it’s possible to inadvertently serve HTTPS content over HTTP, which causes this error.

  1. Open your NGINX configuration file for editing, typically found at /etc/nginx/nginx.conf or in the /etc/nginx/sites-available/ directory.
  2. Ensure that you have a server block listening on the SSL port with ssl on; included right after the listen directive.
  3. If you intend to redirect HTTP traffic to HTTPS, make sure your HTTP server block has the appropriate return directive, like return 301 https://$host$request_uri;
  4. Check for typo errors in the server name, listen directives, or within the SSL configuration parameters, such as the SSL certificate and key paths.
  5. Save the changes and test the configuration by running sudo nginx -t.
  6. If the test is successful, reload NGINX with sudo systemctl reload nginx or sudo nginx -s reload.

Example:

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    #... additional configurations ...
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

Notes: Changing server blocks may interfere with live traffic. Ensure that you test the configuration carefully before reloading NGINX. It is also essential that SSL certificates are kept secure and up to date.

Use NGINX Map Directive

The map directive in NGINX allows you to conditionally define variables based on another variable’s value. You can use this to detect HTTPS requests and handle them correctly.

  1. Add the NGINX map directive in the HTTP context to check the scheme of the request:
  2. Define what should happen when encountering HTTPS or HTTP requests.
  3. Include the correct server blocks that listen either on port 80 for HTTP or 443 for HTTPS.
  4. Save the configuration file changes.
  5. Run the configuration test and reload the NGINX server as described previously.

Example:

http {
    map $scheme $https_redirect {
        default 0;
        http 1;
    }

    server {
        listen 80;
        listen 443 ssl;
        if ($https_redirect) {
            return 301 https://$host$request_uri;
        }

        #... SSL configurations ...
    }
}

Notes: Some pros of using a map directive include that it’s a powerful way to handle complex conditional logic in NGINX. However, overusing ‘if’ can be problematic, as many ‘if’ directives can lead to unpredictable server behavior, so use with caution.

Enable Strict Transport Security

HTTP Strict Transport Security (HSTS) is a header that instructs browsers to only interact with your server over HTTPS. While this does not directly solve the NGINX configuration issue, it can mitigate some of the client-side risks and streamline secure connections.

  1. Open the NGINX configuration file for the SSL server block.
  2. Add the add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; directive to enforce HSTS policy.
  3. Ensure you have a valid SSL certificate configured, as HSTS will require an HTTPS connection.
  4. Save the configuration file and test the changes.
  5. Reload the NGINX server to apply the changes.

Example:

server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    #... rest of the SSL configurations ...
}

Notes: HSTS can greatly improve security, but misconfiguration can make your site inaccessible for the length of the max-age directive if the SSL setup fails. Always test thoroughly.

Conclusion

Resolving NGINX errors related to HTTP and HTTPS mismatches involves careful attention to the configuration details. By employing one of the solutions above, you can ensure that your server properly handles connections and maintains a secure environment for your users.