Cryonel

Why cURL works but browser Fetch fails

A mechanically correct conversion can still fail because cURL and browser JavaScript run in different security environments. Compare the actual request, then identify the browser-only constraint.

Check CORS first

cURL can request any reachable server. Browser Fetch is constrained by the page’s origin and the target server’s Cross-Origin Resource Sharing response headers. If DevTools reports a blocked preflight or missing Access-Control-Allow-Origin, changing Fetch syntax will not solve the problem.

The API owner must return an allowed origin, methods, and headers. Do not work around CORS by disabling browser security or exposing a private API through an unrestricted proxy. For your own backend, allow the exact frontend origins and request headers that are required.

Understand the preflight request

A JSON POST, custom authorization header, or non-simple method can trigger an OPTIONS preflight. The server must answer it before the browser sends the real request. Inspect both requests in the Network panel. A successful cURL POST says nothing about whether the endpoint handles OPTIONS.

Remove browser-controlled headers

Commands copied from DevTools may include Host, Content-Length, Cookie, connection, or browser metadata headers. Page JavaScript cannot safely set all of them. Let the browser calculate transport headers. For cookies, use credentials: "include" only when the server intentionally supports credentialed cross-origin requests.

Compare body and content type

cURL’s --data, --data-urlencode, multipart form uploads, and raw binary bodies are not interchangeable. Ensure the generated body matches the server’s expected media type. JSON usually needs JSON.stringify(value) and Content-Type: application/json; form data should use FormData and let the browser add its multipart boundary.

TLS, redirects, and local networks

cURL may be run with an option that skips certificate validation; Fetch cannot disable TLS verification. Browser mixed-content rules also block insecure HTTP requests from an HTTPS page. Redirects can change methods or remove authorization across origins. A private hostname reachable from your terminal may not be reachable from another user’s browser.

Use a minimal comparison

Convert the command with cURL to Fetch, then remove nonessential headers and retry from the intended page origin. Inspect status, response headers, and the console. Keep bearer tokens out of screenshots and never paste production credentials into public bug reports.

Frequently Asked Questions

Why does cURL ignore CORS while Fetch does not?

CORS is a browser security policy. A terminal HTTP client is not restricted by the page origin.

Can Fetch send the Host header from a cURL command?

No. Browsers control several request headers and do not allow page JavaScript to set them directly.

Does converting cURL to Fetch execute the request?

No. Cryonel only generates code locally; it does not send the request.

Related Tools and Guides