Membrane API Gateway returns 403 Forbidden with a link to this page when the cors plugin rejects a CORS preflight request, because the HTTP method of the planned request is not allowed by the CORS policy. The browser then blocks the actual cross-origin request of the page.
The response contains the status 403 Forbidden, the detail The method '...' is not allowed by the CORS policy., where the quoted value is the method from Access-Control-Request-Method, the problem type https://membrane-api.io/problems/security/method-not-allowed and a link to this page. The type security with the subtype method-not-allowed means that the CORS policy of the gateway refused the request.
Before a web page sends a cross-origin request that is not a simple request, the browser sends a preflight: an OPTIONS request with the headers Origin, Access-Control-Request-Method and, if needed, Access-Control-Request-Headers. The cors plugin checks these values against its origins, methods, headers and credentials settings and answers the preflight itself. If one check fails, it rejects the preflight with this error. The CORS Guide for API Developers explains the background.
The method in Access-Control-Request-Method is not in methods. A page that sends PUT or DELETE requires these methods in the list. The comparison is case-sensitive, so write methods in upper case.
An OPTIONS request with an Origin header but without Access-Control-Request-Method is treated as a preflight for the method null and rejected. Browsers always send the header; this usually comes from hand-written test requests or from clients that send OPTIONS requests for other purposes.
Access-Control-Request-Method header of the failing preflight request.methods.Access-Control-Request-Method.api:
port: 2000
flow:
- cors:
origins: https://app.example.com
methods: GET, POST, PUT, DELETE
target:
url: https://api.predic8.de
api:
port: 2000
flow:
- cors:
origins: https://app.example.com
methods: GET, POST, PUT, DELETE
target:
url: https://api.predic8.de
For development only, allowAll: true skips all CORS checks. Do not use it in production.
Unlike most errors, CORS rejections are sent with the detail and the link to this page even when Membrane runs in production mode. Setting production: true in the configuration document does not remove them.
Configuration reference:
Still stuck? See the troubleshooting guide or ask on GitHub Issues. For commercial support, contact info@predic8.de.