I have posted about this error before but talking about it on another level.
Despite the fact that the original topics were closed as “SOLVED”, this is not solved yet, still an error.
If we send a POST request to a wrong Function URL path, to a non-existent path, the Cloudflare server responds with an error 405: Method not allowed.
This is not a proper response and can make debugging hard.
If the URL path does not exist, the expected HTTP error response is 404: Not found.
Minimum reproduction:
Access this Cloudflare example (from Cloudflare Github): https://submit.pages.dev/
Inspect the page opening DevTools and look for: <form method="POST" action="/api/submit">
Change the action value in HTML to anything, eg.: /api/lorem-ipsum
Click the Submit button on the screen
EXPECTED
The response should be HTTP ERROR 404, which is the proper error for not found resources
ACTUAL
You will see an HTTP ERROR 405, which is not the proper error to a non-existent URL
It is correct, our asset server doesn’t handle POSTs. I understand how it can be confusing but it isn’t wrong. It would be confusing if I got a 404 on POST, it would make me think I could do a POST here when in reality I can’t.
What happens if you POST an existing asset? Should we return 405 then? Return the asset?
I think it is not confusing.
If we GET/POST/PUT/DELETE/… to a non-existing URL, the proper response is 404, ever.
If we GET/POST/PUT/DELETE/… to an existing URL that does not accept the method used to request, then the proper response is 405.
The issue is, our asset server can never handle a POST. So, it is 100% correct for it to return a 405.
If you want 404s, we’d need to run your Function on all paths which would then incur a cost which we don’t want to do. We also fallback to the asset server anyway there… so it would still happen but regardless
There’s 2 different parts at play here, the Function and the asset server. The asset server is returning the 405 because it didn’t run the Function and again, 405 is fully correct in this context.
If you GET an asset which doesn’t exist, yeah you’ll get a 404.
Ok, I got it.
So in this case, only on the Cloudflare Pages Functions server, the 405 response is correct when POST to a NOT FOUND function URL.
Ok, so I think this could be documented.
If 404 Not Found does not seem to be a proper response for the Cloudflare server, in this case, it would be at least a 400 Bad Request, but not a 405 Method Not Allowed.
405 Method Not Allowed - HTTP | MDN
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response status code indicates that the server knows the request method, but the target resource doesn’t support this method.
I agree @cherryjimbo, it is a server issue that can’t be handled by the architecture/engineering used there.
And @Walshy, your answer confirms that the response is really wrong.
The problem is: 405 is not the correct response because it is for the TARGET resource doesn’t support this method, but there is NO TARGET for the request endpoint. 405 means that there is a target, but it does not support the method. 404 means that there is no target.
The asset server is not the target of the request, it is a middleware, a gateway, it should respond to the request properly according to the TARGET requested, not considering itself as the target.
But, ok, this is just my opinion, I can understand if the Cloudflare asset server works in different ways. Maybe has a good reason because I don’t know the architecture/engineering under the hood.
A better and proper response that could make more sense would be:
400 Bad Request
The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (for example, malformed request syntax, invalid request message framing, or deceptive request routing).
For anyone else running into this annoying issue, I suggest this solution:
Give up on Pages Functions!
Switch to “Advanced Mode”, which is nothing else than a Worker. (https://developers.cloudflare.com/pages/platform/functions/advanced-mode/)
Handle the request/response in your Worker and do things correctly.
You can use a router solution to handle requests/responses easily. There is a good one (I guess, never tested it) made to be similar to the Express syntax, it is named worktop (https://github.com/lukeed/worktop).
But if you want a really simple and lightweight solution, with Typescript support and intelligent enough to handle proper HTTP responses for common errors, you can try the module I’ve developed to solve my problems: