Nginx HTTP not redirecting to HTTPS 400 Bad Request "The plain HTTP request was sent to HTTPS port"

13,990

Put the following directive to the server block where you listen for port 443.

error_page 497 https://$host:$server_port$request_uri;

This directive implies that when "The plain HTTP request was sent to HTTPS port" happens, redirect it to https version of current hostname, port and URI.

Kinda hacky but works.

Share:
13,990

Related videos on Youtube

Omair Nabiel
Author by

Omair Nabiel

A programmer with a love for football and travelling

Updated on June 04, 2022

Comments

  • Omair Nabiel
    Omair Nabiel almost 2 years

    I'm running nginx in docker. HTTPS works fine but when I explicitly make HTTP request I get the following error

    400 Bad Request The plain HTTP request was sent to HTTPS port

    nginx.conf is as follows

    worker_processes auto ;          
    events {}
    
    http {
    
    include /etc/nginx/mime.types;
    
    access_log /var/log/nginx/main.access.log;                                           
    
    server {    
    listen 80;                                                                                                       
    location / {
        return 301 https://localhost:3000$request_uri; 
    }
    
    }
    
    server {   
    listen 443 ssl;                                                      
    server_name  localhost:3000;                  
     root    /var/www/html; 
    
    ssl_certificate         /etc/nginx/ssl/cert.pem; 
    ssl_certificate_key     /etc/nginx/ssl/key.pem;
    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
    
    location / {
    try_files  $uri /index.html;        
    }
    
    }
    
    }
    

    I run this container using

    docker run -p 3000:443 -it -d --name nginxtest nginx-test
    

    and get the following error

    docker file is as follows

    FROM nginx:latest
    COPY ./build /var/www/html
    COPY ./nginx.conf /etc/nginx/nginx.conf
    COPY ./ssl /etc/nginx/ssl
    EXPOSE 443
    CMD [ "nginx","-g","daemon off;" ]
    

    Weird thing is that sometimes it works perfectly fine, and all of a sudden it stops working and won't even work if I recreate the containers.

    Even tried doing the following. Still no luck

     server {    
        listen 80;                                                                                                       
         server_name localhost:3000
            return 301 https://localhost:3000$request_uri; 
        }
    

    Another odd thing when I run the following docker command

    docker run -p 3000:443 -p 3001:80 -it -d --name nginxtest nginx-test
    

    and go to localhost:3001 it redirects me to https just fine but other things do break. Sorry for the long question

  • Omair Nabiel
    Omair Nabiel about 5 years
    Man this did work though! Thanks alot. But can you please elaborate a bit as to why it's happening? Am I doing something wrong in the configuration which causes this behaviour. Any proper way of doing it? Hack does work like charm. Day saved. A little more insight would help
  • Yarimadam
    Yarimadam about 5 years
    It happens because you are using non-standart port for https protocol. (which is totally fine.) In a typical https setup you serve https over port 443. And when accessing that setup with https:// prefix you don't put :443 to address bar, browser adds it automatically placing request. (for http:// it adds 80). However, when you are serving https content from non standart port you can try to access like http:// example.com:3000, where nginx expects https requests. And it means "The plain HTTP request was sent to HTTPS port" :).
  • Omair Nabiel
    Omair Nabiel about 5 years
    That makes complete sense. Thanks a alot. Saved my day. Cheers :D
  • Nimesh Kumar
    Nimesh Kumar about 4 years
    Worked for me ! Thanks