error http

HTTP 405 Method Not Allowed

Understanding HTTP 405 Method Not Allowed - the HTTP method used is not supported for the requested resource.

What It Means

HTTP 405 Method Not Allowed indicates that the request method (GET, POST, PUT, DELETE, etc.) is known by the server but is not supported by the target resource. The server must include an Allow header listing the methods that are supported.

For example, trying to POST to a read-only endpoint that only accepts GET requests.

Common Causes

  • Using POST when the endpoint only accepts GET (or vice versa)
  • Sending PUT or DELETE to a resource that only supports GET and POST
  • CORS preflight OPTIONS request not handled
  • Form submitting with the wrong method
  • API client using the wrong HTTP method
  • Missing route definition for the specific method

How to Fix

Check the Allow header

# The response should include an Allow header
curl -I -X POST https://api.example.com/users/123

# HTTP/1.1 405 Method Not Allowed
# Allow: GET, HEAD, PUT, DELETE

Express.js route definition

const express = require('express');
const router = express.Router();

// Define all supported methods explicitly
router.route('/users/:id')
  .get(getUser)       // GET /users/:id
  .put(updateUser)    // PUT /users/:id
  .delete(deleteUser) // DELETE /users/:id
  .all((req, res) => {
    res.status(405)
      .set('Allow', 'GET, PUT, DELETE')
      .json({
        error: 'Method Not Allowed',
        allowed: ['GET', 'PUT', 'DELETE']
      });
  });

Django

from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
def user_list(request):
    if request.method == "GET":
        return JsonResponse({"users": get_users()})
    elif request.method == "POST":
        return JsonResponse({"user": create_user(request)}, status=201)
    # Django automatically returns 405 for other methods

HTML form method fix

<!-- Bad: forms only support GET and POST natively -->
<form method="PUT" action="/api/users/1">...</form>

<!-- Good: use POST with method override -->
<form method="POST" action="/api/users/1">
  <input type="hidden" name="_method" value="PUT">
  ...
</form>

Client-side fix

// Check you're using the right method
// Bad: GET request with body
fetch('/api/users', { method: 'GET', body: JSON.stringify(data) });

// Good: POST request to create
fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(data)
});
  • HTTP 400 - Bad Request: The request syntax is malformed.
  • HTTP 403 - Forbidden: The method is valid but you lack permission.
  • HTTP 404 - Not Found: The resource itself does not exist.
  • HTTP 501 - Not Implemented: The server does not recognize the method at all.