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.

If you liked this article, then do subscribe to email alerts for Linux tutorials. If you have any questions or doubts? do ask for help in the comments section.

If You Appreciate What We Do Here On TecMint, You Should Consider:

TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.

If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.

Support Us

We are thankful for your never ending support.

1 thought 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 zhoulujun Cancel reply

Have a question or suggestion? Please leave a comment to start the discussion. Please keep in mind that all comments are moderated and your email address will NOT be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.