Fix “The plain HTTP request was sent to HTTPS port” Error in Nginx

In this article, we will show how to solve the “400 Bad Request: The plain HTTP request was sent to HTTPS port” in Nginx HTTP server. This error normally arises when you try to configure Nginx to handle both HTTP and HTTPS requests.

For the purpose of this guide, we are considering a scenario in which nginx is serving multiple websites implemented through server blocks (or virtual hosts in Apache) only one website uses SSL and the rest do not.

Read Also: The Ultimate Guide to Secure, Harden and Improve Performance of Nginx

We will also consider the sample SSL configuration below (we have changed the actual domain name for security reasons), which tells nginx to listen to both port 80 and 443. And all requests on HTTP should to be redirected to HTTPS by default.

Nginx Sample Configuration

server{
        listen 80;
        server_name example.com www.example.com;
        return 301 https://www.example.com$request_uri;
}
server {
        listen 443 ssl http2;
        server_name example.com www.example.com;

        root   /var/www/html/example.com/;
        index index.php index.html index.htm;

        #charset koi8-r;
        access_log /var/log/nginx/example.com/example.com_access_log;
        error_log   /var/log/nginx/example.com/example.com_error_log   error;

        # SSL/TLS configs
        ssl on;
        ssl_certificate /etc/ssl/certs/example_com_cert_chain.crt;
        ssl_certificate_key /etc/ssl/private/example_com.key;

        include /etc/nginx/ssl.d/ssl.conf;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   /var/www/html/example.com/;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {

                root   /var/www/html/example.com/;
                fastcgi_pass   127.0.0.1:9001;
                #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include         fastcgi_params;
                include /etc/nginx/fastcgi_params;

        }
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
}

Using the above configuration, once a client tries to access your site via port 80 i.e http://example.com, the error in question will be displayed as in the following screen shot.

Nginx 404 Bad Request Error
Nginx 404 Bad Request Error

You encounter this error because every time a clien tries to access your site via HTTP, the request is redirected to HTTPS. It’s because the nginx expects SSL to be used in the transaction yet the original reques t(received via port 80) was plain HTTP, it complains with the error.

On the other hand, if a client uses https://example.com, they will not encounter the above error. In addition, if you have other websites configured not to use SSL, nginx will try to use HTTPS by default for them resulting to the above error.

To fix this error, comment out the line below in your configuration or set it to off.

#ssl on 
OR
ssl off

Save and close the file. Then restart the nginx service.

# systemctl restart nginx
OR
$ sudo systemctl restart nginx

This way, you can enable nginx to handle both HTTP and HTTPS requests for multiple server blocks.

Finally, below is a list of articles about setting up SSL HTTPS on common Linux distributions and FreeBSD.

  1. Setting Up HTTPS with Let’s Encrypt SSL Certificate For Nginx on RHEL/CentOS
  2. Secure Nginx with Free Let’s Encrypt SSL Certificate on Ubuntu and Debian
  3. How to Secure Nginx with SSL and Let’s Encrypt in FreeBSD

That’s all for now. If you know of any other way to solve this error, please let us know via the feedback form below.

Aaron Kili
Aaron Kili is a Linux and F.O.S.S enthusiast, an upcoming Linux SysAdmin, web developer, and currently a content creator for TecMint who loves working with computers and strongly believes in sharing knowledge.

Each tutorial at TecMint is created by a team of experienced Linux system administrators so that it meets our high-quality standards.

Join the TecMint Weekly Newsletter (More Than 156,129 Linux Enthusiasts Have Subscribed)
Was this article helpful? Please add a comment or buy me a coffee to show your appreciation.

3 thoughts on “Fix “The plain HTTP request was sent to HTTPS port” Error in Nginx”

  1. It’s not working, this is my Nginx configuration.

    server {
        ssl off;
        server_name media.zhoulujun.cn;
        listen 80;
        root  /data/wwwroot/zhoulujun/media;
    }
    
    server
    {
        server_name www.zhoulujun.cn 193.112.222.61;
        listen 80 default_server;
        index index.php index.html index.htm;
        root  /data/wwwroot/zhoulujun;
        error_log /var/log/nginx/default-error.log crit;
        client_max_body_size 10m;
    
    Reply

Leave a Reply to kibble Cancel reply

Thank you for taking the time to share your thoughts with us. We appreciate your decision to leave a comment and value your contribution to the discussion. It's important to note that we moderate all comments in accordance with our comment policy to ensure a respectful and constructive conversation.

Rest assured that your email address will remain private and will not be published or shared with anyone. We prioritize the privacy and security of our users.