CORS Troubleshooting
This guide covers CORS configuration, common errors, debugging techniques, browser network inspection, and production patterns for Adobe Commerce Storefronts.
CORS configuration
If using a CORS module with admin UI configuration (such as graycore/magento2-cors), navigate to Stores → Configuration → General → Web → CORS Whitelist in the Adobe Commerce admin panel.
The following configuration options are typically available.
Allowed Origins
Add your storefront URLs, one per line (no trailing slashes):
http://localhost:3000http://localhost:5173https://staging-storefront.example.comhttps://storefront.example.com
Allow Credentials
Enable this setting if your storefront needs to:
- Send authentication cookies
- Include session cookies
- Send credentials with cross-origin requests
When enabled, the Access-Control-Allow-Credentials: true
header will be sent.
Allowed Methods
Specify HTTP methods your storefront uses (comma-separated):
GET,POST,OPTIONS
Understanding preflight requests
Before sending the actual request, browsers send an OPTIONS request (called a “preflight”) to check if the cross-origin request is allowed. This happens automatically for requests with:
- Custom headers (like
Authorization
) - Methods other than GET/POST/HEAD
- Content-Type other than basic types
The OPTIONS request asks: “Can I send a POST request with these headers?” The server responds with allowed methods, headers, and origins.
Allowed Headers
Specify headers your storefront sends (comma-separated):
Content-Type,Authorization,X-Requested-With,Store
Common headers include:
Content-Type
: For JSON requestsAuthorization
: For bearer tokensStore
: For multistore configurationsX-Requested-With
: For AJAX requests
Common CORS errors
The following are standard CORS errors enforced by browser security policies. These error messages appear in the browser console (DevTools).
Common issues
If you encounter CORS errors after installing adobe-commerce/storefront-compatibility
, verify that your CORS implementation is compatible with Adobe Commerce Storefronts. If using the graycore module, ensure v2.x or later is installed.
Debug checklist
Distinguishing CORS errors from server-side errors
When debugging, it’s important to distinguish CORS policy failures from server-side GraphQL exceptions. Here’s an example of a server-side error that might be mistaken for a CORS issue:
{ "message": "Internal server error", "extensions": { "debugMessage": "Magento\\InventoryConfiguration\\Model\\IsSourceItemManagementAllowedForProductType\\Interceptor::execute(): Argument #1 ($productType) must be of type string, null given" }}
This indicates a PHP/GraphQL issue (inventory configuration or compatibility) and not a missing Access-Control-Allow-Origin header.
Edge cases and special scenarios
Docker and containerized environments
When running Commerce in Docker, you may need to add multiple origin variations:
http://localhost:3000http://127.0.0.1:3000http://host.docker.internal:3000
Multiple storefronts
For multiple storefronts accessing the same Commerce backend, add each origin separately:
https://storefront-us.example.comhttps://storefront-eu.example.comhttps://storefront-asia.example.com
Each storefront is treated as a separate origin and must be explicitly allowed.
Adobe Commerce Cloud vs on-premise
Adobe Commerce Cloud
- CORS configuration works the same way
- Ensure the module is installed in your environment
- Configuration syncs across Cloud environments through standard config management
On-premise
- No differences in the CORS setup
- You have full control over all infrastructure
Production best practices
The recommended production approach is to avoid CORS entirely by serving both the storefront and the backend from the same domain using a CDN proxy.
Same-origin architecture (recommended)
Serve both your storefront and Commerce backend from the same domain:
- Storefront:
https://example.com
→ CDN serves static assets - GraphQL API:
https://example.com/graphql
→ CDN proxies to Commerce backend
This requires configuring your CDN to proxy /graphql
requests to your Commerce backend.
Benefits:
- No CORS complexity
- Better performance (fewer preflight requests)
- Simpler security model
- Better caching control
Implementation approaches:
-
Fastly VCL routing: Configure Fastly to route GraphQL requests to your Commerce backend using VCL (Varnish Configuration Language). The VCL detects requests to
/graphql
and proxies them to your backend origin while serving other requests from your storefront origin. -
Cloudflare Workers / CDN Edge Functions: Use edge functions to route API requests to your backend dynamically.
-
Reverse proxy (Nginx/Apache): Configure your web server to proxy
/graphql
requests to the backend.
Note: This approach requires CDN/infrastructure expertise. If you don’t have these resources, use CORS configuration instead.
CORS configuration
If you must use different domains (for example, storefront.example.com
→ commerce.example.com
), use CORS configuration. Use specific allowed origins for single production domains, or a wildcard *
when you have multiple dynamic preview URLs (such as Edge Delivery Services branch previews).
References
CORS standards and specifications
- CORS specification - MDN Web Docs on Cross-Origin Resource Sharing
- CORS errors - MDN documentation on common CORS error messages
- CORS headers - Complete list of CORS-related HTTP headers
- Preflight requests - How browsers use OPTIONS requests for CORS
Adobe Commerce
- Adobe Commerce CLI commands - Official documentation for Magento CLI commands used in this guide
- Adobe Commerce GraphQL - GraphQL API documentation
Additional tools and platforms
- Composer documentation - PHP dependency manager used for module installation
- Docker networking - Understanding Docker hostname resolution for CORS origins
- Fastly VCL documentation - For implementing same-origin architecture with Fastly CDN routing