Debug the web path
Classify CORS and TLS errors
Distinguish a browser CORS policy block, a server HTTP response, and a TLS identity failure.
10 minute lesson
Browser console errors mix three different failures that need three different fixes. Classifying the error correctly is most of the work.
CORS is enforced by browsers after or around an HTTP exchange: the server may have responded fine, but the response lacked the Access-Control-Allow-Origin header your page’s origin needs, so the browser withheld it from your JavaScript. TLS failure happens before protected HTTP — the connection never became trustworthy, so no request went through at all. A plain HTTP error (a 403, a 500) means everything worked except the application.
The key tool fact: curl does not enforce browser CORS policy. That difference is diagnostic.
Compare evidence:
curl -v https://api.lab.test/data
# browser: inspect Console and Network panels for CORS details
# TLS: openssl s_client -connect api.lab.test:443 -servername api.lab.test
If curl gets a normal response while the browser reports CORS, the server and network are fine. Inspect the Origin request header and the Access-Control-* response headers — the server is not authorizing your page’s origin, or the preflight OPTIONS request fails.
If curl also fails with a certificate complaint, it is TLS, and the openssl s_client output names which kind:
certificate has expired -> validity window, renew it
hostname mismatch -> cert issued for another name
unable to get local issuer -> server sent an incomplete chain
If TLS fails, repair certificates first. CORS symptoms on top of broken TLS mean nothing — the browser never got far enough for CORS to matter.
The fix that is worse than the bug
Do not fix CORS by reflecting every Origin with credentials. Echoing whatever origin arrives into Access-Control-Allow-Origin, combined with Access-Control-Allow-Credentials: true, lets any website make authenticated requests as your logged-in users. Authorize the exact browser origins required, as a fixed list.
The same discipline applies to TLS: never “fix” it by disabling verification with curl -k in a saved script or NODE_TLS_REJECT_UNAUTHORIZED=0. That turns a loud error into a silent opening for a man-in-the-middle.
Lesson completed