405 Method Not Allowed: What It Means and How to Fix It
A 405 Method Not Allowed means the URL exists but doesn't accept the HTTP method you used — a POST to a route that only handles GET, for example. The usual causes in Express, Next.js route handlers, Flask and FastAPI, static hosts and Nginx, plus how CORS preflight OPTIONS requests trigger it.
405 Method Not Allowed means: "This address exists, but it doesn't accept that kind of request." You sent a POST to something that only handles GET, or a DELETE to a route that doesn't support it.
The server should include an Allow header listing what it does accept:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Check that header first — it tells you what the route expects. (GET vs POST)
Common causes
1. The route handler only defines one method
Express:
app.get('/api/users', listUsers) // GET works
// POST /api/users → 404 or 405, because no app.post() exists
app.post('/api/users', createUser) // add the method you need
Next.js App Router route handlers export one function per method. If app/api/users/route.ts only exports GET, a POST returns 405:
export async function GET() { /* ... */ }
export async function POST(request: Request) { /* add this */ }
Flask: routes default to GET only:
@app.route('/api/users', methods=['GET', 'POST'])
FastAPI: @app.get(...) and @app.post(...) are separate; you need both. (What Is FastAPI?)
2. A form or fetch uses the wrong method
An HTML <form> without method="post" sends GET. A fetch() without method: 'POST' sends GET. Check the Network tab in DevTools to see what was actually sent.
3. Posting to a static host
Static hosting (GitHub Pages, a plain S3 bucket, Nginx serving files) only serves files with GET. A form that posts to /contact on a static site gets a 405 because there's no backend to receive it. You need a backend or a form service. (Contact Form Without a Backend)
4. Trailing slashes and redirects
Some frameworks redirect /api/users to /api/users/. A redirect turns many POSTs into GETs, so the request arrives with the wrong method. Use the exact URL the route defines.
5. CORS preflight (OPTIONS)
Before certain cross-origin requests, browsers send an OPTIONS "preflight" request. If your server doesn't handle OPTIONS for that route, it may answer 405 and the browser reports a CORS error. Use your framework's CORS middleware, which handles OPTIONS for you. (CORS Errors Explained)
6. Nginx sitting in front
Nginx serving static files returns 405 for POST. If your API requests are hitting Nginx's static location instead of being proxied to your app, fix the location blocks so /api/ goes to the backend. (Nginx Reverse Proxy Configuration)
The summary
- 405 = right URL, wrong HTTP method. Read the
Allowheader. - Add the missing method to your route handler, or send the right method from the client.
- Watch for static hosts, redirects, CORS preflights and Nginx routing.
EasySpawn runs your frontend and backend together on one server with routing set up correctly, so POST /api/... reaches your code instead of a static file server. See how it works or join the waitlist.
Related: REST API Design · HTTP Status Codes Explained · 400 Bad Request · How to Test an API
Keep reading
What Is UTF-8? Character Encoding and Garbled Text (Mojibake) Explained
UTF-8 is the character encoding that lets computers store every language and emoji as bytes — and it's the default almost everywhere now. How encoding works, why you see garbled text like ’ or é, and how to fix it in HTML, databases, CSV files and code.
"User Is Not in the Sudoers File": What It Means and How to Fix It
"username is not in the sudoers file. This incident will be reported." means your Linux user isn't allowed to run commands as root with sudo. How to add a user to the sudo (or wheel) group from root, edit sudoers safely with visudo, recover when you've locked yourself out, and the safer alternatives to giving out sudo.