GuidesDIAGNOSE

Redirect is not allowed for a preflight request

The browser error Redirect is not allowed for a preflight request occurs when an OPTIONS check hits an HTTP redirect before the actual request can execute. Browsers require cross-origin preflight requests to terminate directly at the resource without any intermediate 3xx hops.

The exact console message

Chrome console
Access to fetch at 'https://api.example.com/data' from origin 'https://your-site.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

Chrome prints this wording when an OPTIONS preflight request answers with a 3xx status code. Firefox reports its own reason for the same failure, CORS request external redirect not allowed, or logs a failed preflight.

What the browser is telling you

When a browser prepares a cross-origin request that requires a preflight check, it issues an HTTP OPTIONS request to the server. If the target URL responds with any 3xx redirect status code, the browser aborts the request immediately.

By design, browsers refuse to follow redirects during a preflight. Because the preflight check fails instantly, the real request never leaves the browser.

Where the redirect comes from

  • HTTP to HTTPS upgrades: The API listens on both protocols and issues a 301 redirect from HTTP to HTTPS, but the frontend code calls the insecure URL.
  • Apex to www canonicalization: The server canonicalizes traffic by redirecting example.com to www.example.com, or the reverse, and the client specifies the non-canonical origin.
  • Trailing slash normalization: Frameworks redirect between paths with and without slashes, such as Django issuing a redirect to the slashed URL via APPEND_SLASH or other routers using 307 or 308 status codes.
  • Load balancer or CDN canonicalization: An edge routing rule enforces a canonical path or host before the request reaches the application, returning a redirect that carries no CORS headers.

Fix: call the final URL directly

Preflight requests cannot follow redirects under any circumstance. Resolve this by identifying the redirection destination and pointing the client directly to that final URL.

  1. Inspect the redirect target

    Use curl or the browser devtools Network tab to identify the 3xx response and extract the exact destination from the Location header.

  2. Point the client at the final URL

    Copy the Location header value into your frontend environment variables, API client base URLs, or application configuration.

  3. Remove redirects from API routes

    Configure backend routers to serve the requested resources directly without 3xx hops, and update external consumers to avoid relying on redirects.

  4. Verify destination CORS headers

    Ensure that the final URL returns valid Access-Control-Allow-* headers on both the preflight OPTIONS request and the subsequent application response.

Reveal the hidden redirect
$ curl -i https://api.example.com/data \
    -X OPTIONS \
    -H "Origin: https://your-site.com" \
    -H "Access-Control-Request-Method: POST"

HTTP/2 301
location: https://www.example.com/api/data

# Any 3xx on the preflight URL fails the request before it starts.
# Point the client at the location target instead.

Verify the fix

Verify the endpoint using a manual OPTIONS request that includes an Origin header and an Access-Control-Request-Method header. A compliant endpoint returns a 2xx status code such as 204 with the required Access-Control-Allow-* headers and no 3xx status.

Confirm the final URL answers OPTIONS directly
$ curl -i https://www.example.com/api/data \
    -X OPTIONS \
    -H "Origin: https://your-site.com" \
    -H "Access-Control-Request-Method: POST"

HTTP/2 204
access-control-allow-origin: https://your-site.com
access-control-allow-methods: POST

# A direct 2xx answer with the allow headers, and no 3xx in sight.

Good questions.

Does setting redirect: 'follow' in fetch resolve this error?

No. The default behavior for fetch is already redirect: 'follow', but that configuration only controls the main request. Browsers unconditionally reject redirects encountered during an OPTIONS preflight.

Why did this request trigger a preflight check?

Preflight requests occur whenever a cross-origin call uses non-safelisted methods like PUT or DELETE, includes custom request headers, or sets a Content-Type other than text/plain, multipart/form-data, or application/x-www-form-urlencoded, such as application/json.

Will a 307 or 308 redirect preserve the preflight method?

No. While 307 and 308 status codes preserve the HTTP method for standard requests, browsers do not permit any 3xx status code for preflights. Every redirect status causes the preflight to fail.

Can the server add CORS headers to a 3xx response to make it pass?

No. The browser rejects preflight redirects regardless of what headers are present on the 3xx response. The request must reach the canonical URL directly without an initial redirect.