Skip to content

[Bug]: HTTP reverse proxy swallows OPTIONS requests — breaks CORS preflight for extensions #7324

Description

@0xtlt

Problem

The HTTP reverse proxy used by shopify app dev intercepts OPTIONS requests
and never forwards them to the target application. This breaks CORS preflight
for any cross-origin call made from UI extensions (e.g. Customer Account
extensions calling the app backend through the Cloudflare tunnel).

The root cause is in packages/app/src/cli/utilities/app/http-reverse-proxy.ts:
the proxy forwards every method but does not handle OPTIONS specially, and
http-proxy silently drops the preflight — the request never reaches the
user's app, so no CORS headers are returned.

Expected behavior

An OPTIONS preflight request to the tunnel URL should either:

  • be forwarded to the target app so it can respond with its own CORS headers, or
  • be answered at the proxy level with correct CORS headers.

Actual behavior

The OPTIONS request gets a response with no CORS headers (no
Access-Control-Allow-Origin, etc.). The browser then blocks the actual
request. The request never appears in the app's logs.

Reproduction

  1. Run shopify app dev (any backend — Express, Remix, etc.)
  2. From an extension (or curl):
    curl -i -X OPTIONS \
      -H "Origin: https://extensions.shopifycdn.com" \
      -H "Access-Control-Request-Method: GET" \
      https://<tunnel>.trycloudflare.com/any-path
  3. Response has no CORS headers → browser blocks the follow-up request.

Opening the tunnel directly with cloudflared tunnel --url … works fine,
confirming the issue is in the CLI's reverse proxy, not Cloudflare.

Impact

Any extension that makes a cross-origin fetch to the app backend during local
dev is affected. Common case: Customer Account UI extensions calling app API
routes.

Related

Environment

  • OS: macOS
  • Shopify CLI: 3.x
  • Node: 22.x

Activity

  1. 0xtlt commented on Apr 30, 2026

    @0xtlt
    ContributorAuthor

    Sorry to ping this but this is still an issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions