I am experiencing a persistent and intermittent CORS policy error for users accessing my website, specifically for API calls made from my frontend on https://[my-domain] to my backend on https://[my-domain]:8443.
The Problem:
Users intermittently receive the following CORS error in their browser console:
Access to XMLHttpRequest at 'https://[my-domain]:8443/user/game-setting' from origin 'https://[my-domain]' has been blocked by CORS policy: Request header field p-authorization is not allowed by Access-Control-Allow-Headers in preflight response.
This error occurs during the browserâs preflight OPTIONS request, which is triggered because my frontend includes a custom header (P-Authorization).
My Setup:
-
Frontend: React application hosted on https://[my-domain].
-
Backend: Express.js application running on my origin server, listening directly on port 8443 using HTTPS.
-
CORS Configuration: My Express application uses the cors middleware with the default configuration (app.use(cors());), which should allow all origins and reflect requested headers in the Access-Control-Allow-Headers response.
-
Cloudflare: My domain [my-domain] is managed by Cloudflare.
Debugging Performed:
-
Direct API Access: Accessing the API endpoint directly via the browser address bar (e.g., https://[my-domain]:8443/user/game-setting?token=âŚ) works correctly. This confirms the backend endpoint logic and token validation are functional, and that GET requests without custom headers (which bypass preflight) succeed.
-
Backend CORS Check: Iâve verified my backend code uses app.use(cors()); with default settings, which should correctly handle the OPTIONS preflight and allow the p-authorization header.
-
curl -v Test: I used curl -v -X OPTIONS https://[my-domain]:8443/user/game-setting -H âOrigin: https://[my-domain]â -H âAccess-Control-Request-Method: GETâ -H âAccess-Control-Request-Headers: p-authorizationâ from an external network to simulate the browserâs preflight request.
Contradictory curl -v Results:
Running the curl -v command at different times yields inconsistent results for the CORS response headers.
Attempt 1 (Problematic Response - Matches User Error):
< HTTP/2 200
< date: Mon, 19 May 2025 17:33:38 GMT # Example date
... other headers ...
< access-control-allow-origin: https://[my-domain]
< access-control-allow-methods: POST,OPTIONS
< access-control-max-age: 86400
< vary: Origin
< access-control-allow-credentials: true
< access-control-allow-headers: Content-Type <-- PROBLEM HERE!
... Cloudflare headers ...
< server: cloudflare
< cf-ray: [some-ray-id] # Example Ray ID
... other headers ...
Interpretation: This response came from Cloudflare (indicated by server: cloudflare, cf-ray). It incorrectly specified Access-Control-Allow-Headers: Content-Type, causing the browser to block the request that requires P-Authorization. Note the absence of Express-specific headers like X-Powered-By.
Attempt 2 (Correct Response - Matches Expected Backend Behavior):
< HTTP/2 204
< date: Mon, 19 May 2025 17:49:04 GMT # Example date
< x-powered-by: Express <-- Indicates request reached my origin
< access-control-allow-origin: *
< access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE # Matches cors() defaults
< vary: Access-Control-Request-Headers
< access-control-allow-headers: p-authorization <-- CORRECT headers for preflight
... Cloudflare headers ...
< server: cloudflare
< cf-ray: [some-different-ray-id] # Example Ray ID
... other headers ...
Interpretation: This response shows the request reached my Express origin (x-powered-by: Express). My Express appâs default cors() middleware correctly handled the OPTIONS request and responded with Access-Control-Allow-Headers: p-authorization. Cloudflare headers (server: cloudflare, cf-ray) are still present, showing itâs in the path.
Conclusion:
Based on the curl outputs, Cloudflare is confirmed to be in front of my application on port 8443 and is intermittently intercepting or responding to the OPTIONS preflight requests before they consistently reach my origin server (where Express is configured to handle them correctly). Sometimes Cloudflare seems to pass the request through, and sometimes it sends a response with incorrect/incomplete CORS headers (Access-Control-Allow-Headers: Content-Type).
The intermittent nature and the different responses suggest a possible issue with Cloudflareâs caching of OPTIONS responses or inconsistent edge behavior on port 8443.
Request for Assistance:
-
Why is Cloudflare interfering with/responding to OPTIONS requests on port 8443, and why is this behavior intermittent? (Is this expected behavior for Spectrum or other configurations on non-standard ports?)
-
How can I configure Cloudflare to consistently ensure that for requests to https://[my-domain]:8443:
-
It includes p-authorization (and content-type, authorization) in the Access-Control-Allow-Headers response for OPTIONS requests from the https://[my-domain] origin.
-
Ideally, could Cloudflare be configured to not add CORS headers on 8443 and simply pass the OPTIONS request to my origin so my backendâs cors() middleware can handle it consistently?
- Could a Cloudflare cache issue be causing the intermittent problem? I have tried purging the cache, but the issue persists for some users.
Please guide me on where in the Cloudflare dashboard (Spectrum, Workers, Firewall rules, etc.) I should look for the configuration that is adding or modifying headers on port 8443, and how to adjust it to resolve this intermittent CORS error for my users.