Nginx 405 Not Allowed Error

Posted by Curtis Miller Curtis Miller

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



Velocity Labs

Need web application development, maintenance for your existing app, or a third party code review?

Velocity Labs can help.

Hire us!