Architecture

API Gateway 403 Missing Authentication Token: Configuration Fixes

2026-05-13 · 9 min read

You have just deployed your API and you are testing it with curl. The response comes back:

{
  "message": "Missing Authentication Token"
}

HTTP status: 403. You stare at this for a moment. You are not using authentication on this endpoint. It is a public API. Why is API Gateway asking for an authentication token?

Here is the thing most developers learn the hard way: this error message is one of the most misleading in all of AWS. In the majority of cases, "Missing Authentication Token" does not mean you are missing an authentication token. It means the resource you are requesting does not exist. API Gateway returns this 403 instead of a 404 for security reasons — it does not want to reveal which paths exist and which do not.

Let me walk through all the causes of this error and how to systematically diagnose each one.

Step 1: Verify the API and Stage Exist

Start by confirming you are hitting the correct API endpoint. Get the list of your REST APIs:

aws apigateway get-rest-apis \
  --query 'items[*].{Name:name,Id:id,CreatedDate:createdDate}' \
  --output table

Then verify the stage exists:

aws apigateway get-stages \
  --rest-api-id YOUR_API_ID \
  --query 'item[*].{StageName:stageName,DeploymentId:deploymentId,LastUpdated:lastUpdatedDate}' \
  --output table

The API Gateway invoke URL format is:

https://{api-id}.execute-api.{region}.amazonaws.com/{stage}/{resource}

A wrong API ID, wrong region, or wrong stage name will all produce the "Missing Authentication Token" error. I have seen teams waste hours debugging authentication when the actual problem was prod vs production in the stage name.

Root Cause 1: Resource Path Does Not Exist

The most common cause. You are requesting /users/123 but the API only has /user/123 defined (singular vs plural), or the resource was defined as /users/{id} but you are hitting /users without the path parameter.

List all resources in the API:

aws apigateway get-resources \
  --rest-api-id YOUR_API_ID \
  --query 'items[*].{Id:id,Path:path,Methods:resourceMethods}' \
  --output table

This shows you every path and which HTTP methods are configured on each. If your requested path is not in this list, that is your answer.

Common mismatches:

  • /api/v1/users vs /v1/users (extra prefix)
  • /users/{userId} vs /users/{id} (the path variable name does not matter for routing, but the path structure does)
  • /users/ vs /users (trailing slash — API Gateway treats these as different resources)

Root Cause 2: Changes Not Deployed to the Stage

This catches people regularly. You added a new resource or method in the API Gateway console or via the API, but you did not create a new deployment. API Gateway has a two-step process: define the API, then deploy it to a stage. Changes to the API definition are not live until deployed.

Check the latest deployment:

aws apigateway get-deployments \
  --rest-api-id YOUR_API_ID \
  --query 'items[*].{Id:id,CreatedDate:createdDate,Description:description}' \
  --output table

Compare the deployment ID on the stage with the latest deployment:

# Get the deployment ID currently on the stage
aws apigateway get-stage \
  --rest-api-id YOUR_API_ID \
  --stage-name prod \
  --query '{DeploymentId:deploymentId,LastUpdated:lastUpdatedDate}' \
  --output table

If the stage's deployment ID does not match the latest deployment, create a new deployment:

aws apigateway create-deployment \
  --rest-api-id YOUR_API_ID \
  --stage-name prod \
  --description "Deploy new resources"

Root Cause 3: Missing API Key in the Request

If your API method requires an API key (apiKeyRequired: true), and the request does not include the x-api-key header, you get the "Missing Authentication Token" error.

Check if the method requires an API key:

aws apigateway get-method \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method GET \
  --query '{ApiKeyRequired:apiKeyRequired,AuthorizationType:authorizationType}' \
  --output table

If ApiKeyRequired is true, you need to include the API key in your request:

curl -H "x-api-key: YOUR_API_KEY" \
  https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/prod/users

Also verify the API key is associated with a usage plan that includes your API stage:

# List usage plans
aws apigateway get-usage-plans \
  --query 'items[*].{Name:name,Id:id,ApiStages:apiStages}' \
  --output json
# List API keys in a usage plan
aws apigateway get-usage-plan-keys \
  --usage-plan-id YOUR_USAGE_PLAN_ID \
  --query 'items[*].{Name:name,Id:id,Type:type}' \
  --output table

Root Cause 4: IAM Authorization Without SigV4 Signing

If the method's authorization type is AWS_IAM, every request must be signed with Signature Version 4. A request without SigV4 signing will receive the "Missing Authentication Token" error.

Check the authorization type:

aws apigateway get-method \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method GET \
  --query 'authorizationType' \
  --output text

If this returns AWS_IAM, you need to sign your requests. Using the AWS CLI:

# Use the awscurl tool for SigV4-signed requests
pip install awscurl

awscurl --service execute-api \
  --region us-east-1 \
  "https://YOUR_API_ID.execute-api.us-east-1.amazonaws.com/prod/users"

Or if you want to switch to open access for testing:

aws apigateway update-method \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method GET \
  --patch-operations op=replace,path=/authorizationType,value=NONE

# Don't forget to deploy after changing
aws apigateway create-deployment \
  --rest-api-id YOUR_API_ID \
  --stage-name prod

Root Cause 5: Cognito Authorizer Misconfiguration

If you are using a Cognito User Pool authorizer, several misconfigurations can cause the 403 error:

  • The Authorization header contains an expired or invalid JWT token
  • The authorizer is configured with the wrong User Pool ID
  • The token's audience (aud claim) does not match the App Client ID configured in the authorizer
  • The token is an access token but the authorizer expects an ID token (or vice versa)

Check the authorizer configuration:

aws apigateway get-authorizers \
  --rest-api-id YOUR_API_ID \
  --query 'items[*].{Name:name,Type:type,ProviderARNs:providerARNs,IdentityValidationExpression:identityValidationExpression}' \
  --output json

Verify the token is valid by decoding it (JWT tokens are base64-encoded):

# Decode the JWT payload (middle segment)
echo "YOUR_JWT_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool

Check the exp (expiration), aud (audience), and iss (issuer) claims. The issuer should match your Cognito User Pool URL: https://cognito-idp.{region}.amazonaws.com/{userPoolId}.

Root Cause 6: CORS Preflight OPTIONS Method Not Configured

When a browser makes a cross-origin request, it first sends an OPTIONS preflight request. If your API does not have an OPTIONS method configured on the resource, the preflight fails with the "Missing Authentication Token" error, and the browser blocks the actual request.

Check if OPTIONS is configured:

aws apigateway get-resources \
  --rest-api-id YOUR_API_ID \
  --query 'items[?path==`/users`].resourceMethods' \
  --output json

If OPTIONS is not in the list, you need to add it. The OPTIONS method should return CORS headers and should not require authentication:

# Create the OPTIONS method
aws apigateway put-method \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method OPTIONS \
  --authorization-type NONE

# Set up a mock integration (OPTIONS doesn't need a backend)
aws apigateway put-integration \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method OPTIONS \
  --type MOCK \
  --request-templates '{"application/json": "{\"statusCode\": 200}"}'

# Configure the response with CORS headers
aws apigateway put-method-response \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method OPTIONS \
  --status-code 200 \
  --response-parameters '{
    "method.response.header.Access-Control-Allow-Headers": false,
    "method.response.header.Access-Control-Allow-Methods": false,
    "method.response.header.Access-Control-Allow-Origin": false
  }'

aws apigateway put-integration-response \
  --rest-api-id YOUR_API_ID \
  --resource-id RESOURCE_ID \
  --http-method OPTIONS \
  --status-code 200 \
  --response-parameters '{
    "method.response.header.Access-Control-Allow-Headers": "'\''Content-Type,Authorization,X-Api-Key'\''",
    "method.response.header.Access-Control-Allow-Methods": "'\''GET,POST,OPTIONS'\''",
    "method.response.header.Access-Control-Allow-Origin": "'\''*'\''"
  }'

Remember to deploy after adding the OPTIONS method.

Root Cause 7: Custom Domain Base Path Mapping Issues

If you are using a custom domain name (e.g., api.example.com) with API Gateway, the base path mapping can cause routing issues. If the mapping includes a base path like v1, then api.example.com/v1/users maps to /users on the API. But if you request api.example.com/users directly, it will not match any resource.

Check the base path mappings:

aws apigateway get-base-path-mappings \
  --domain-name api.example.com \
  --query 'items[*].{BasePath:basePath,RestApiId:restApiId,Stage:stage}' \
  --output table

If the base path is v1, your requests must include /v1/ in the path. If you want the root to map directly, set the base path to (none).

Root Cause 8: WAF Blocking the Request

If you have AWS WAF associated with your API Gateway, a WAF rule might be blocking the request. WAF blocks can appear as 403 errors that look identical to the "Missing Authentication Token" response.

Check if WAF is associated with the API stage:

aws wafv2 get-web-acl-for-resource \
  --resource-arn arn:aws:apigateway:us-east-1::/restapis/YOUR_API_ID/stages/prod \
  --query 'WebACL.{Name:Name,Id:Id}' \
  --output table

If a WAF is attached, check the WAF logs to see if your request is being blocked:

aws wafv2 list-web-acls \
  --scope REGIONAL \
  --query 'WebACLs[*].{Name:Name,Id:Id,ARN:ARN}' \
  --output table

WAF blocks typically return a different response body than the standard "Missing Authentication Token" message, but not always — custom WAF response bodies can mimic the API Gateway error response.

Diagnosis Workflow

When you see "Missing Authentication Token," follow this order:

  1. Verify the URL — correct API ID, region, stage, and resource path
  2. Check if the resource existsget-resources to list all paths
  3. Check if changes are deployed — compare stage deployment ID with latest
  4. Check the auth type — is it NONE, AWS_IAM, CUSTOM, or COGNITO_USER_POOLS?
  5. For API keys — verify x-api-key header and usage plan association
  6. For IAM auth — ensure requests are SigV4-signed
  7. For Cognito — validate the JWT token's claims
  8. For CORS — check if OPTIONS method exists on the resource
  9. For custom domains — verify the base path mapping
  10. For WAF — check if rules are blocking the request

Prevention Best Practices

  1. Use CloudWatch access logging on your API stages. This gives you the full request path, method, and response code for every request, making it trivial to spot path mismatches:
aws apigateway update-stage \
  --rest-api-id YOUR_API_ID \
  --stage-name prod \
  --patch-operations op=replace,path=/accessLogSettings/destinationArn,value=arn:aws:logs:us-east-1:123456789012:log-group:api-gateway-access-logs
  1. Automate deployments. Never rely on manual deployments to stages. Use CI/CD pipelines that always create a deployment after updating the API definition.

  2. Use OpenAPI/Swagger definitions to manage your API. Import the full API definition on each deployment so you never have out-of-sync resources.

  3. Enable detailed CloudWatch metrics and set up alarms on 4xx error rates to catch configuration issues before users report them.

  4. Test with curl before deploying clients. A simple curl command with verbose output (curl -v) reveals the exact URL, headers, and response, cutting through abstraction layers that can hide the real problem.

Need Help with API Gateway Configuration?

API Gateway's error messages can send you down the wrong debugging path for hours. If your API is returning unexpected 403s, or you are building a new API and want to get the authentication, CORS, and custom domain configuration right from the start, we can help. Contact us for a free AWS consultation — we have configured hundreds of API Gateway deployments and can quickly identify what is causing your 403 errors.

Need help with your AWS infrastructure?

Book a free 30-minute consultation to discuss your challenges.