AWS API Gateway Error: CORS Failures That Aren’t CORS

 

AWS API Gateway Error: CORS Failures That Aren’t CORS

How to diagnose API Gateway requests that fail in browsers due to preflight handling, authorization behavior, gateway-generated errors, or response configuration—when the backend itself is working correctly





Problem

You invoke an endpoint exposed through Amazon API Gateway from a browser-based application, and the request fails with a CORS-related error.

In the browser console, you see messages such as:

Access to fetch at 'https://api.example.com/resource'
from origin 'https://app.example.com'
has been blocked by CORS policy

Yet confusingly:

  • The same request works with curl
  • The same request works in Postman
  • The backend executes correctly when called directly

It looks like a CORS configuration issue—but it often isn’t.


Clarifying the Issue

Browsers enforce CORS. API Gateway does not.

Most “CORS errors” in API Gateway fall into one of two categories:

  1. The preflight OPTIONS request never succeeds
  2. API Gateway generates an error response that lacks CORS headers

In both cases, the browser blocks the response before your application code ever runs.

The browser then reports a generic CORS error, hiding the real HTTP status code (403429500) that actually explains what went wrong.


Why It Matters

This is one of the most deceptive failure modes in API Gateway because:

  • The backend may be healthy
  • The API may be correctly implemented
  • The real failure is upstream (throttling, WAF, auth, missing API key)
  • The browser hides the true error behind a CORS message

Teams often respond by:

  • Adding more CORS headers
  • Modifying backend logic
  • Weakening security controls

None of which fix the real problem.

Understanding where the response was generated—API Gateway vs backend—is the key to resolving this class of issues.


Key Terms

  • CORS (Cross-Origin Resource Sharing) – Browser security model for cross-origin requests
  • Preflight Request – Automatic OPTIONS request sent by the browser
  • OPTIONS Method – HTTP method used for CORS negotiation
  • Gateway Response – A response generated directly by API Gateway (4xx/5xx)
  • Method Response – Declares which headers API Gateway may return
  • Integration Response – Maps headers from integration to method response
  • MOCK Integration – An API Gateway integration that returns a static response without invoking a backend

Steps at a Glance

  1. Confirm this is a browser-only failure
  2. Understand browser preflight behavior
  3. Verify the OPTIONS method exists
  4. Ensure OPTIONS is not authorized
  5. Validate Method & Integration Responses
  6. Check API Gateway Gateway Responses
  7. Retest from the browser

Detailed Steps

Step 1: Confirm the Failure Is Browser-Only

You are in the correct Fix-It if:

  • Browser requests fail with CORS errors
  • curl or Postman requests succeed
  • Backend logs show no corresponding request

This confirms the failure occurs before backend invocation.


Step 2: Understand the Browser Preflight

For many requests, browsers automatically issue:

OPTIONS /resource

The browser expects headers such as:

Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers

If the preflight fails, the browser:

  • Never sends the real request
  • Never shows backend errors
  • Reports a generic CORS failure

Step 3: Verify the OPTIONS Method Exists

For REST APIs:

  • OPTIONS must be explicitly defined per resource
  • OPTIONS must be deployed to the stage

Missing or undeployed OPTIONS results in immediate browser failure.


Step 4: Ensure OPTIONS Is Not Authorized

This is one of the most common mistakes.

If authorization (IAM, Cognito, Lambda authorizer) is applied to OPTIONS:

  • Preflight fails with 401403, or 500
  • Browser reports a CORS error

Best practice:
OPTIONS methods should typically have no authorization.


Step 5: Validate Method & Integration Responses (OPTIONS)

For REST APIs, OPTIONS is typically implemented using a MOCK integration.

This is why:

  • You manually configure response headers
  • Mapping templates are required
  • There is no backend execution

You must configure both:

Method Response

Declare:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

Integration Response

Map static values, for example:

Access-Control-Allow-Origin: '*'
Access-Control-Allow-Methods: 'GET,POST,OPTIONS'
Access-Control-Allow-Headers: 'Content-Type,Authorization'

If headers are not declared and mapped, API Gateway silently drops them.


Step 6: Check API Gateway Gateway Responses (Critical Step)

This is the most commonly missed cause of “mystery CORS errors.”

If API Gateway itself generates a response—such as:

  • 403 Forbidden (WAF, missing API key, auth failure)
  • 429 Too Many Requests (throttling)
  • 5xx errors (internal gateway failures)

That response comes from Gateway Responses, not your backend.

By default, Gateway Responses do NOT include CORS headers.

Result:

  • Browser receives a response without Access-Control-Allow-Origin
  • Browser blocks it
  • Developer sees a CORS error instead of the real 403 or 429

To fix this:

  • Customize Gateway Responses
  • Add CORS headers to relevant 4xx/5xx responses

Pro Tips

  • A CORS error may hide a real 403 or 429.
  • If the backend didn’t run, stop debugging backend code.
  • OPTIONS usually uses a MOCK integration—expect manual config.
  • Authorization on OPTIONS breaks preflight.
  • Gateway Responses must include CORS headers for browser visibility.
  • curl success does not imply browser success.

Conclusion

Most API Gateway “CORS errors” are not caused by missing headers in your backend.

They occur because:

  • Preflight OPTIONS requests fail
  • Authorization blocks OPTIONS
  • API Gateway generates an error response without CORS headers

Once you recognize that browsers hide real HTTP failures behind CORS messages, debugging becomes systematic.

Fix the preflight.
Fix the Gateway Responses.
The browser will follow.


Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.

Comments

Popular posts from this blog

The New ChatGPT Reason Feature: What It Is and Why You Should Use It

Insight: The Great Minimal OS Showdown—DietPi vs Raspberry Pi OS Lite

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison