The HTTP method you used (GET, POST, PUT, DELETE, etc.) is not supported for this URL. The resource exists, but it does not accept the method you sent. The server should include an Allow header listing which methods are accepted.
HTTP 405 Method Not Allowed is a client error status code indicating that the HTTP method used in the request is known by the server but is not supported by the target resource. The key distinction from 404 is that the resource at the URL does exist, but it does not accept the method the client used. The server is required to include an Allow response header listing the methods that the resource does support, giving the client clear guidance on how to make a valid request.
This status code most commonly appears during API integration when developers use the wrong HTTP method for an endpoint. For example, sending a DELETE request to an endpoint that only supports GET, or sending a POST to a resource that requires PUT for updates. It also appears when web frameworks have a route defined for a URL but not for the specific combination of URL and method. In these cases, the framework returns 405 rather than 404 because the URL path is valid, just not for the method used.
Another common scenario for 405 is CORS preflight failures. When a browser sends an OPTIONS request to check cross-origin permissions and the server does not have an OPTIONS handler, the server may return 405 instead of the expected 204 with CORS headers. This causes the browser to block the actual request entirely. Properly handling OPTIONS requests is essential for any API that serves cross-origin clients.
Sending a POST request to an endpoint that only accepts GET. This often happens when developers confuse retrieval endpoints with creation endpoints, or when frontend code sends the wrong method.
The web framework has a route defined for the URL but not for the specific HTTP method. For example, a route handles GET /api/users but not DELETE /api/users.
Attempting to modify a resource on a read-only endpoint. Some APIs expose GET-only endpoints for data retrieval and return 405 for any mutation attempts.
The server does not handle OPTIONS requests correctly, causing preflight checks to fail with 405. The server must explicitly allow the OPTIONS method for CORS to work.
The 405 response must include an Allow header listing the methods the endpoint supports. Use this to determine the correct method for your request.
Verify which HTTP method the endpoint expects. Common patterns are GET for retrieval, POST for creation, PUT/PATCH for updates, and DELETE for removal.
If 405 occurs on preflight requests, add an OPTIONS handler that returns 204 with the correct Access-Control-Allow-Methods header. Many frameworks have CORS middleware that handles this automatically.
Verify that your web framework has a route handler registered for the combination of URL path and HTTP method you are targeting. A missing handler for a specific method causes 405.
// Express.js — handling method restrictions with Allow header
const express = require('express');
const app = express();
// Only allow GET and POST on /api/users
app.route('/api/users')
.get(async (req, res) => {
const users = await User.findAll();
res.json(users);
})
.post(async (req, res) => {
const user = await User.create(req.body);
res.status(201).json(user);
})
.all((req, res) => {
// Any other method gets 405 with Allow header
res.set('Allow', 'GET, POST');
res.status(405).json({
error: 'Method Not Allowed',
message: `${req.method} is not supported on /api/users`,
allowedMethods: ['GET', 'POST']
});
});
// Handle OPTIONS globally for CORS
app.options('*', (req, res) => {
res.set('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,DELETE');
res.set('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.status(204).end();
});
# Flask — handling method restrictions with Allow header
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/api/users', methods=['GET', 'POST'])
def users():
if request.method == 'GET':
users = User.query.all()
return jsonify([u.to_dict() for u in users])
if request.method == 'POST':
data = request.get_json()
user = User(name=data['name'], email=data['email'])
db.session.add(user)
db.session.commit()
return jsonify(user.to_dict()), 201
@app.errorhandler(405)
def method_not_allowed(error):
return jsonify(
error='Method Not Allowed',
message=f'{request.method} is not supported on {request.path}',
allowed_methods=error.valid_methods or []
), 405
A 405 occurs when you send an HTTP method that the endpoint does not support. Common causes include using POST instead of GET, missing route handlers for specific methods, and CORS preflight failures from missing OPTIONS handlers.
The Allow header is required in 405 responses and lists the HTTP methods the resource supports, such as Allow: GET, POST, PUT. This tells the client exactly which methods can be used on that endpoint.
Yes. HTTP 404 means the resource at the URL does not exist at all. HTTP 405 means the resource exists but does not accept the HTTP method you used. The distinction helps developers understand whether the URL is wrong or the method is wrong.
Add an OPTIONS handler to your server that returns 204 with the Access-Control-Allow-Methods header. Most web frameworks have CORS middleware that adds this automatically.
Return 405 when the URL exists but the method is wrong. Return 404 when the URL itself does not match any route. Use 405 to be helpful: the Allow header tells the client which methods will work.
Get instant alerts when your endpoints go down. 60-second checks, free forever.
Start Monitoring Free →