I currently have nginx running behind AWS Application Load Balancer. I have a ghost blog on another server which I have setup using proxy_pass. It works perfectly if I go to https://www.example.com/blog

However, I have a link to https://www.example.com/blog on my homepage, but when I click on it it seems to 301 redirect me to http://www.example.com:443/blog resulting in "The plain HTTP request was sent to HTTPS port"

The site is also setup to 301 HTTP to HTTPS. This appears to work flawlessly.

ALB is taking care of my SSL certs. To keep it simple I have the ALB setup with two listeners (80 and 443) but only one process (80). I previously had 443 setup as another process but have removed it to reduce potential failure points.

I'm at a loss as to why it would be 301'ing a perfectly good url by turning it into HTTP on port 443 when in all other cases it appears to turn HTTP into HTTPS.

Some suggested answers were to add listener 443 ssl; to the nginx.conf but I cant do that as no SSL certs are setups on nginx. It's all on ALB.

worker_processes  1;

events {
    worker_connections  1024;

http {
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;

    listen 80;
    listen 443; 
    server_name example.com;

    return 301 https://www.example.com;


server {
    listen 80;
    listen 443; 
    server_name www.example.com;

    if ($http_x_forwarded_proto = 'http'){
        return 301 https://$host$request_uri;

    sendfile on;

    default_type application/octet-stream;

    gzip on;
    gzip_http_version 1.1;
    gzip_disable      "MSIE [1-6]\.";
    gzip_min_length   256;
    gzip_vary         on;
    gzip_proxied      expired no-cache no-store private auth;
    gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_comp_level   9;

    root /usr/share/nginx/html;

    location / {
        try_files  $uri $uri/ /blog/$uri;

    location /blog/ {
        proxy_pass https://ip.address;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;



include servers/*;

Any ideas??


proxy_pass handles https/http as protocol specifiers, you need to set port when proxying to https on port 443: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

proxy_pass https://ip.address:443;

Also don't do ifs, they are evil: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ Better way is to add distinct server for http requests:

server {
  listen 80;
  return 302 https://$host$uri;

And don't use $request_uri there, this way you support sending arguments over unencrypted link. Stripping them will make people look for the error cause and use https to link to your site.

| improve this answer | |
  • Good call out but didnt' fix it unfortuantely.. Still getting the same error. I am confused as to how the proxy_pass routing seems to work (as I can access example.com/blog fine) but it only breaks with the link. It actually tries to turn the link to HTTP despite all the config doing the opposite.. – Max Oct 3 '18 at 6:28

Okay this worked for me:

I added port_in_redirect off; to the second server block.

Proxy pass with the additional :433 port didnt seem to have an impact. The issue appears to be related to this: https://serverfault.com/a/905740/201084

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.