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 a rewrite rule working and I've discovered that if the URL begins with a question mark, Nginx fails to return 404 error as expected. Instead, index.html as defined in the root directive is served for all urls beginning with "?". (e.g. works for the home page but should not)

This is making it impossible to get a redirect from -> working. This is for a blog migrated from Joomla to Jekyll.

Put simply, visiting returns a 404, and visiting does not. The latter returns the site's home page at the URL (There is no file or folder '123', so requests for it should always fail.)

Everything works perfectly with the site, including the HTTPS redirect, except for the expected 404 redirects not happening for URLs starting with a question mark. How do I fix this?

Here's my configuration:

server {
    root /var/www/;
    index index.html;
    listen 443;
    ssl on;      

    rewrite "/?format=feed&type=rss" permanent;

    location ~* \.(?:ico|css|js|gif|jpeg|jpg|png|txt|svg|eot|woff|ttf)$ {
            expires max;
            add_header Pragma public;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
            add_header Access-Control-Allow-Origin *;
            valid_referers none blocked;
            if ($invalid_referer) {
                    return 403;

server {
        listen 80;
        return 301$request_uri;
share|improve this question
up vote 3 down vote accepted

The question mark signifies the end of the path portion of the uri and the beginning of the query string. Hence why nginx will not return 404 based on the portion after the question mark; the requested resource does exist and the query string parameters are just passed to it.

Regarding the other part of the question, I believe that nginx's rewrite statement does not actually match against the query string portion of the uri.

You should however be able to do something along the lines of:

if ($args ~ "format=feed&type=rss") {
    rewrite ^ permanent;
share|improve this answer
Nginx's docs say 'if is evil' and recommend against using it, plus this unfortunately didn't work when I just tested it. I still get the home page for instead of a redirect or 404. – Tom Brossman Apr 18 '14 at 22:36
Do you actually have & in your query strings? I assumed that was a mistake in the question and you really meant &? (HTML encoding things in the query string seems like really weird practice.) – Håkan Lindqvist Apr 18 '14 at 22:38
I have subscribers requesting both types subscribed to the RSS feed, so ultimately I'd like both to work. I'm getting hits for /?format=feed&type=rss and /?format=feed&type=rss. – Tom Brossman Apr 18 '14 at 22:41
Ok, and my suggestion does not work for the /?format=feed&type=rss case? (Which seems like the sane case.) – Håkan Lindqvist Apr 18 '14 at 22:44
No, didn't work and I'm sure I copied it exactly. it returns with a "The page isn't redirecting properly" error. Tested with it in the main server block + in a location / {...} block, same thing. (plus obviously reloading Nginx each time. – Tom Brossman Apr 18 '14 at 22:59

NGinx interprets everything that follows a ? as a query string, not as a path.

It will only return a 404 for a non-existing path, not for a query string.

eg :

  • : if path /123 exists and if there is an index file for this path then it's OK, else it will return a 404

  • : if there is an index file in the root directory for then it's OK. It does not check if directory ?123 exists as it does not consider this as a path but as a query string.

share|improve this answer
So is it possible to either redirect or rewrite requests for to something else. or is this impossible with Nginx? (I can ask this as a new question if that's best) – Tom Brossman Apr 18 '14 at 22:38
You are right to ask it here, i think it's possible, will have look at it right now. But there is something that confuse me : you do a rewrite for /?format=feed&type=rss, so i am not sure which exact case you want to handle. – user216707 Apr 18 '14 at 22:42
Joomla's default RSS feed for the old site was which some feed readers (I'm guessing?) replace with as the second type has 3x the hits in my logs. I want both to redirect or rewrite to permanently – Tom Brossman Apr 18 '14 at 22:49
So the previous answer provides the solution. IfIsEvil, for sure, but have a look at the first sample on the IfIsEvil page : There are cases where you simply cannot avoid using an if – user216707 Apr 18 '14 at 22:58

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.