Millarian Millarian
Search
Nginx 405 Not Allowed Error

405 Not Allowed

So, I got this error today and it took me a few minutes to track down why. Seems like the kind of thing that might be interesting to people. I’m using nginx on a project and this error was being thrown by nginx, not by Rails. What could be the cause?

Nginx configuration and REST

Do you have something in your nginx config file that looks like this?

if (-f $request_filename) {
  break;
}

Basically, render an existing, static file directly, aka. bypass Rails. This is great, we don’t incur the overhead of hitting Rails for static files, including cached files, right? Wrong.

You see, with REST, your URL will be the same for a POST to create as it will for a GET to index. For example, viewing the users index and creating a user:

GET  /users <= user's index
POST /users <= create a user

See the problem?

That’s right, if you cache the user’s index using a technique like caches_page then you have a static file (e.g., users.html) that matches regardless of the HTTP method. Therefore, it will bypass rails and attempt to serve the static file on a POST request, resulting in a 405 error. Whew!

Caching with nginx

So what do you do? I don’t know. But this is what I did and I hope it helps. Add the following to your nginx config prior to the serving of static files.

if ($request_method != GET) {
  proxy_pass http://foobar;
  break;
}

Uh, where foobar is the name you specified in the upstream declaration in the nginx config. This should pass any non-GET request to Rails immediately since we don’t want to statically serve files for anything other than GET.

References

arrow5 Responses

  1. -23443 mos, 1 wk ago

    thanks, i long time find howto fix 405 error

  2. -23443 mos, 1 wk ago

    zomg, i was totally stumped until i read this.

    Thanks!

  3. Jimmy
    -23443 mos, 1 wk ago

    This fixed my issue as well. Thank you very much!

  4. Mars
    -23443 mos, 1 wk ago

    helped me, too… Thanks!

  5. 49 mos, 4 wks ago

    Or use this workarround:
    error_page 405 = @405;

    location = @405 {
    root …;
    }

Leave A Comment