# How workerd Handles Cross-Origin Requests: Server-Side Fetch Without Browser CORS Enforcement

> Discover how workerd handles cross-origin requests, bypassing browser CORS for server-side fetch. Learn about its unique approach and compatibility flags.

- Repository: [Cloudflare/workerd](https://github.com/cloudflare/workerd)
- Tags: internals
- Published: 2026-03-18

---

**`workerd` handles cross-origin requests by forwarding them directly to the upstream server without performing browser-style CORS validation, only stripping the `Authorization` header on cross-origin redirects when the `StripAuthorizationOnCrossOriginRedirect` compatibility flag is enabled.**

Unlike browsers that enforce strict Cross-Origin Resource Sharing (CORS) policies, the Cloudflare `workerd` runtime implements a server-side Fetch API that leaves CORS validation to the upstream server or the worker script itself. Understanding this behavior is critical for developers building edge functions that interact with third-party APIs, as `workerd` does not automatically block requests based on origin mismatches or generate preflight responses.

## No Built-In CORS Preflight or Mode Enforcement

The `workerd` runtime does not implement the CORS protocol as specified for web browsers. When you create a `Request` object in `workerd`, several CORS-related fields are explicitly marked as unimplemented in the source code, including `mode`, `credentials`, `referrer`, and `referrerPolicy`.

In `src/workerd/api/http.c++`, the Request constructor notes these limitations:

```cpp
// src/workerd/api/http.c++ – Request constructor notes
// .mode is unimplemented
// .credentials is unimplemented
// .referrer is unimplemented
// .referrerPolicy is unimplemented

```

Because these fields are ignored, setting `mode: 'cors'` or `credentials: 'include'` has no effect on the request execution. The runtime forwards the HTTP request exactly as specified—including all headers, methods, and body content—without checking `Origin` headers or validating `Access-Control-Allow-Origin` responses. Any CORS validation must be performed by the upstream server or manually implemented within the worker script.

## Authorization Header Stripping on Cross-Origin Redirects

The only automatic cross-origin handling `workerd` provides involves redirect behavior. When the `stripAuthorizationOnCrossOriginRedirect` feature flag is enabled, the runtime removes the `Authorization` header when following a redirect to a different origin. This implements the Fetch specification's rule for "CORS non-wildcard request-header names," which currently applies only to the `Authorization` header.

The redirect handling logic in `src/workerd/api/http.c++` (lines 1764–1788) implements this check:

```cpp
// src/workerd/api/http.c++ – redirect handling
if (FeatureFlags::get(js).getStripAuthorizationOnCrossOriginRedirect()) {
  auto base   = urlList.back().toString();
  auto cur    = JSG_REQUIRE_NONNULL(jsg::Url::tryParse(base.asPtr()), TypeError,
                                   "Invalid current URL; unable to follow redirect.");
  auto loc    = JSG_REQUIRE_NONNULL(jsg::Url::tryParse(location, base.asPtr()), TypeError,
                                   "Invalid Location header; unable to follow redirect.");
  if (cur.getOrigin() != loc.getOrigin()) {
    // Delete the only CORS‑non‑wildcard request‑header name: "Authorization"
    jsRequest->getHeaders(js)->deleteCommon(capnp::CommonHeaderName::AUTHORIZATION);
  }
}

```

This security measure prevents accidental credential leakage when an upstream server redirects to an unexpected third-party domain. The feature is controlled through compatibility flags defined in [`src/workerd/io/features.h`](https://github.com/cloudflare/workerd/blob/main/src/workerd/io/features.h) and configured via `src/workerd/io/compatibility-date.capnp`.

## Practical Implementation Examples

### Basic Cross-Origin Fetch Without CORS Enforcement

When fetching resources from different origins, `workerd` sends the request without modification:

```javascript
// worker.js – simple cross-origin fetch
export default {
  async fetch(request, env) {
    // No `mode` support – the request is sent as‑is.
    const resp = await fetch('https://api.example.com/data', {
      headers: { Authorization: 'Bearer secret' },
    });
    // The response is returned unchanged.
    return resp;
  },
};

```

If the upstream server redirects to a different origin and the `StripAuthorizationOnCrossOriginRedirect` flag is active, the `Authorization` header is automatically removed before following the redirect.

### Enabling the Strip-Auth Feature Flag

To activate the authorization stripping behavior, add the compatibility flag to your worker configuration:

```toml

# workerd config (worker.toml)

[[services]]
name = "my-worker"
worker = { modules = [{ name = "worker", esModule = embed "worker.js" }] }

[[services.compatibility_flags]]

# Enable stripping Authorization on cross‑origin redirects

"StripAuthorizationOnCrossOriginRedirect"

```

With this configuration enabled, any cross-origin redirect will have the `Authorization` header removed before the subsequent request is dispatched.

### Manually Implementing CORS in Worker Scripts

Since `workerd` does not add CORS response headers automatically, you must implement CORS handling explicitly when serving browser clients:

```javascript
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    
    // Handle preflight OPTIONS requests
    if (request.method === 'OPTIONS') {
      return new Response(null, {
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
          'Access-Control-Allow-Headers': 'Authorization, Content-Type',
        },
      });
    }
    
    const resp = await fetch(url);
    const newResp = new Response(resp.body, resp);
    newResp.headers.set('Access-Control-Allow-Origin', '*');
    return newResp;
  },
};

```

This pattern allows full control over CORS policies while leveraging `workerd`'s server-side fetch capabilities.

## Key Source Files for Cross-Origin Handling

Understanding the implementation requires examining these specific files in the `cloudflare/workerd` repository:

- **`src/workerd/api/http.c++`**: Contains the core Fetch implementation, redirect handling logic, and feature-flag checks for header stripping.
- **[`src/workerd/io/features.h`](https://github.com/cloudflare/workerd/blob/main/src/workerd/io/features.h)**: Declares the `FeatureFlags` structure, including the `stripAuthorizationOnCrossOriginRedirect` flag.
- **`src/workerd/io/compatibility-date.capnp`**: Lists available compatibility flags that control runtime behavior.
- **[`src/wpt/fetch/api-test.ts`](https://github.com/cloudflare/workerd/blob/main/src/wpt/fetch/api-test.ts)**: Web Platform Tests that verify Fetch behavior, including CORS-related expectations.

## Summary

- **`workerd` does not enforce browser CORS rules**: The runtime forwards cross-origin requests exactly as specified, ignoring `mode` and `credentials` options.
- **Authorization stripping is opt-in**: The only automatic cross-origin handling is the removal of the `Authorization` header on cross-origin redirects when the `StripAuthorizationOnCrossOriginRedirect` compatibility flag is enabled.
- **No preflight generation**: `OPTIONS` requests are treated as standard HTTP requests; `workerd` does not generate or validate CORS preflight responses.
- **Manual CORS implementation required**: Developers must add `Access-Control-Allow-Origin` and related headers manually when serving browser-based clients.

## Frequently Asked Questions

### Does workerd block cross-origin requests by default?

No, `workerd` does not block cross-origin requests. Unlike browsers, which enforce same-origin policies and require CORS headers to permit cross-origin access, `workerd` forwards requests to any origin without validation. The runtime operates as a server-side environment, leaving origin-based access control to the upstream server or the worker script's logic.

### Why does my Authorization header disappear on redirects?

If your `Authorization` header is missing after a redirect, the `StripAuthorizationOnCrossOriginRedirect` compatibility flag is likely enabled in your deployment. This feature automatically removes the `Authorization` header when a redirect crosses origin boundaries to prevent credential leakage to unintended domains. Check your compatibility flags in `src/workerd/io/compatibility-date.capnp` or your runtime configuration.

### How do I enable CORS for browser clients in workerd?

You must manually implement CORS handling by inspecting incoming requests and setting appropriate response headers. For `OPTIONS` preflight requests, return a response with `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, and `Access-Control-Allow-Headers` headers. For actual requests, copy these headers onto the response before returning it to the client.

### What happens if I set mode: 'cors' in a fetch call?

The `mode` property is currently unimplemented in `workerd` according to `src/workerd/api/http.c++`. Setting `mode: 'cors'` or any other mode value has no effect on the request execution. The runtime sends the request exactly as configured without performing CORS checks or modifying headers based on the mode setting.