Nginx: Force HTTPS.

This is a guide on how to force HTTPS on an Nginx web server.

To do this, we will need to tell Nginx to redirect all non-HTTPS traffic on port 80 to port 443. This is because 443 is the standard TCP port for SSL.

301 Redirect.

When forcing HTTPS, it important that you use a 301 Redirect. A 301 Redirect tells search engines that a resource has been permanently moved to a new URL.

As a result, your new HTTPS-enabled pages will replace your old URLs and you will avoid any loss in rankings.

If you fail to use a 301 Redirect, search engines may penalize you for duplicate content.

Using the Nginx IF directive.

The Nginx web server allows you to use IF directives inside server blocks. As a result, we can check the $scheme variable and force a redirect if necessary.


if ($scheme = http) {
    return 301 https://$server_name$request_uri;

In this case, we placed the IF directive above inside the server block of my configuration file, which was located at: /etc/nginx/sites-available/default

This IF directive checks the $scheme variable to see if it is equal to http. If the scheme is equal to http, then we simply force a 301 Redirect to the HTTPS alternative.

Using separate server blocks.

There are a few people who believe that the Nginx IF directive is “evil” and should never be used.

If you are one of these, then you can create two separate server blocks. One server block will listen on port 80 and the other server block with listen on port 443. If a request comes in on port 80, then we will redirect it to the HTTPS version of our website.

#server block for port 80 / non-HTTPS traffic.
server {
    listen 80;
    listen [::]:80;


    return 301 https://$server_name$request_uri;

#server block for port 443 / HTTPS traffic.
server {
    listen   443 default_server ssl;


    ssl_certificate /path/to/your/ssl/cert;
    ssl_certificate_key /path/to/your/ssl/key;

As you can see, we created two separate server blocks.

The first server block is listening for non-HTTPS requests on port 80. If our server receives a request port 80, we “return” a 301 status code and tell Nginx to redirect to the HTTPS version of the URL.

The second server block handles HTTPS requests on port 443. As you might have noticed, we have set this to be the default server by using Nginx’s “default_server” parameter.

To make a long story short, we are forcing HTTPS by redirecting all requests that we receive in the first server block to the second server block, which is SSL-enabled.

Once you have made your changes, you can test the Nginx configuration by using the following Linux command.

nginx -c /etc/nginx/nginx.conf -t

If your configuration passes the test, simply restart Nginx and the changes will take effect.

See also.