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

When I browse to this URL: http://localhost:8080/foo/%5B-%5D server (nc -l 8080) receives it as-is:

GET /foo/%5B-%5D HTTP/1.1

However when I proxy this application via nginx (1.1.19):

location /foo {
        proxy_pass    http://localhost:8080/foo;

The same request routed through nginx port is forwarded with path decoded:

GET /foo/[-] HTTP/1.1

Decoded square brackets in the GET path are causing the errors in the target server (HTTP Status 400 - Illegal character in path...) as they arrive un-escaped.

Is there a way to disable URL decoding or encode it back so that the target server gets the exact same path when routed through nginx? Some clever URL rewrite rule?

share|improve this question
Reported bug to nginx: – Tomasz Nurkiewicz Dec 21 '12 at 12:51
up vote 6 down vote accepted

Quoting Valentin V. Bartenev (who should get the full credit for this answer):

A quote from documentation:

  • If proxy_pass is specified with URI, when passing a request to the server, part of a normalized request URI matching the location is replaced by a URI specified in the directive

  • If proxy_pass is specified without URI, a request URI is passed to the server in the same form as sent by a client when processing an original request

The correct configuration in your case would be:

location /foo {
   proxy_pass http://localhost:8080;
share|improve this answer
I had to change http://localhost:8080/ to http://localhost:8080 in case anyone has the same situation as I did. – herrtim Aug 22 '13 at 20:23
Why does Nginx decode the URI before passing it to the backend server? Wouldn't it make more sense if it kept the URI untouched? – platypus Jan 7 '14 at 7:46

There is an answer by Igor Sysoev to this problem: (you can try using this config:

location /foo {
   proxy_pass    http://localhost:8080/foo;


Also, there is HttpSetMiscModule than can help you:

share|improve this answer
Not my downvote, but your configuration snippet is the same as in my question. Maybe you are missing something in your answer? – Tomasz Nurkiewicz Jan 8 '13 at 8:23

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.