Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to get Nginx to rewrite incoming requests to a site my server prefixed with https:// to http:// (this is because a CMS used on this site forces URIs instead of relative paths -- essentially breaking the whole site by making images, scripts, and stylesheets unavailable).

I'm currently trying to retrofit an existing directive put in place by a predecessor, but I find myself limited by my knowledge of Nginx config syntax. Here's the code:

if ($ssl_protocol = "") {
    rewrite ^   https://$http_host$request_uri? permanent;

I've current commented this code out to prevent forcible rewrites of http:// to https://, but I can't reverse the process without breaking the site. Here's what I've tried so far:

if ($ssl_protocol = "https") {
    rewrite ^   http://$http_host$request_uri? permanent;


# also tried ($ssl_protocol != "")
if (!($ssl_protocol = "")) {
    rewrite ^   http://$http_host$request_uri? permanent;

The first one doesn't seem to have an effect. The HTML sent to the client still makes HTTPS requests that aren't being rewritten.

The second snippet doesn't appear to have any effect either - if I understand correctly (although I'm still somewhat surprised), Nginx doesn't support boolean negation.

What would be the best way (or a working way) to do this?

EDIT: I've tried adding the code from @NathanC's answer; however, this unconditional rewrite causes a redirect loop. Help is still appreciated.

share|improve this question
up vote 4 down vote accepted

The cleaner, way would be:

if ( $scheme = "https" ) {
    return 301$request_uri

or somewhere between that and Nathans answer, where your default ssl server block contains simply the return 301 (whichever ssl block it is, you'll have to take a close look at yours to see how its implemented and adapt) No point in doing regex for a simple redirect

return -

edit: i just noticed there is a variable $https that can be used in the if statement instead. Returns " " if not https:

if ( $https = "on" ) {

Keep in mind, while testing changes, you should use a 302 temporary redirect instead of 301 permanent, to save hair-pulling when you discover you fixed it an hour earlier but the changes didn't reflect in your browser :)

share|improve this answer
Thanks, this seems to work! I'm still hitting an issue with an ERR_INSECURE_RESPONSE happening when the resources are being requested using https but returned over http, but that should be a relatively simple fix. – user3620306 May 9 '14 at 14:16
it may require stepping back and finding the root of why there are https requests in the code when you don't want them, otherwise i believe that would continue to be an issue for embedded resources... – pete May 9 '14 at 14:18
It was part of the Drupal site configuration, actually. The site's set to – user3620306 May 9 '14 at 14:27
+1 for "Keep in mind" paragraph :) – Curious Aug 18 '15 at 8:39

You don't even need this since you can just force all https traffic to go http like so:

server {
        listen 443;
        ssl on;
        rewrite ^(.*)$1 permanent;


share|improve this answer
Put this in my nginx.conf, but I'm getting *unknown directive: "server" in */etc/nginx/nginx.conf:5. – user3620306 May 9 '14 at 13:01
I got it to work - sort of. Using your code, the page enters a redirect loop. – user3620306 May 9 '14 at 13:24
Do you have a redirect from http to https anywhere on the site? This code's a bit of a "hammer" in that it redirects all https on the specified domain. – Nathan C May 9 '14 at 14:27
@pete's answer solved the redirect loop issue - as he explained, in his code, the redirect occurs iff the requested URL/URI starts with an https:// scheme. – user3620306 May 9 '14 at 14:55

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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