Skip to content

HTTP API AWS_PROXY route integration never invokes Lambda (instant generic 500, zero invocation trace) — works fine as an authorizer or via direct CLI invoke

0

I have an HTTP API (API Gateway v2) in us-east-2 with a $default route pointed at a Lambda function via an AWS_PROXY integration (PayloadFormatVersion 2.0). Every request to it returns an immediate, generic error:

{"message":"Internal Server Error"}

as HTTP 500, in ~150-200ms. The target Lambda function is never actually invoked — no CloudWatch Logs entries at all (no START/END/REPORT lines), and no corresponding CloudTrail data event.

What works, for contrast:

  • Invoking the same Lambda function directly via aws lambda invoke (CLI) succeeds immediately and correctly, every time.
  • A Lambda REQUEST authorizer attached to the same API (API Gateway invoking a different Lambda function, specifically as the route's authorizer rather than its integration target) succeeds in ~2ms, confirmed via CloudWatch Logs.

What fails: the same "API Gateway invokes a Lambda function" mechanism, specifically when that Lambda is the route's AWS_PROXY integration target.

Reproduction:

  1. Create a minimal Lambda (Python 3.12) returning {"statusCode":200,"headers":{...},"body":"..."}.
  2. aws apigatewayv2 create-api --protocol-type HTTP --target <function-arn> (quick-create).
  3. aws lambda add-permission granting apigateway.amazonaws.com lambda:InvokeFunction on the function, condition AWS:SourceArn = arn:aws:execute-api:us-east-2:<account-id>:<api-id>/*/*/* (verified present and correctly scoped via get-policy — even added a second, redundant permission statement to double-check, no change).
  4. curl -X POST https://<api-id>.execute-api.us-east-2.amazonaws.com/ with a JSON body.
  5. Get the generic 500 above; confirm via aws logs tail /aws/lambda/<function-name> that the function was never invoked.

I repeated this with:

  • The original function — fails.
  • A brand-new, completely trivial function with no dependencies/secrets/non-default config — fails identically.
  • A brand-new HTTP API (not reusing the original API resource) pointed at that same trivial function — fails identically.

Also tried a Lambda Function URL (AuthType: NONE) as an alternative — got an immediate 403 Forbidden pointing to the Function URL auth troubleshooting doc, despite a correctly-configured public resource policy (Principal: "*", Action: lambda:InvokeFunctionUrl, condition matching FunctionUrlAuthType: NONE).

Ruled out so far:

  • Not an AWS Organizations SCP/RCP — account is not a member of an Organization.
  • Not a WAF Web ACL — none associated with any resource in us-east-2 (checked regional scope specifically, not just the CloudFront/Global scope).
  • Not an AWS Config rule — zero Config rules exist, no configuration recorder is even set up.
  • Not IAM Access Analyzer — not enabled in this account.
  • Not Lambda concurrency/throttling — no reserved concurrency set, only 2 functions total in the account.
  • Not a resource-based policy issue — verified correct via get-policy, and adding a second redundant permission statement changed nothing.
  • Not a payload format mismatch — a format mismatch would still let the function execute (producing a malformed response that API Gateway then fails to parse), so CloudWatch Logs would show a completed invocation. We see zero log entries at all, meaning the function is never started. The authorizer, which also uses PayloadFormatVersion 2.0, invokes and completes successfully every time.
  • Not fixed by a stage redeploy (triggered update-stage, new deployment succeeded, behavior unchanged).

I don't have a support plan tier that allows opening a technical Support case, so I'm hoping someone here has seen this exact failure mode before — API Gateway invoking Lambda successfully as an authorizer but never as a route's proxy integration target, in the same account, same region, same permission model. What else differentiates those two invocation paths internally that could explain this?

1 Answer
1
Accepted Answer

Based on the symptoms you're describing—immediate 500 errors with no Lambda invocation logs—this strongly suggests a permissions issue specific to the integration invocation path, even though your resource-based policy appears correct on the surface.

The key difference between the authorizer working and the integration failing is that API Gateway uses different invocation contexts for these two scenarios. When API Gateway invokes a Lambda authorizer versus invoking a Lambda integration, the source ARN pattern and permission requirements can be subtly different.

For HTTP APIs specifically, the resource-based policy condition should use a more specific ARN pattern. Your current wildcard pattern arn:aws:execute-api:us-east-2:<account-id>:<api-id>/*/*/* may be too broad or not matching the actual invocation context. Try granting permission with a more targeted condition:

aws lambda add-permission \
--function-name <function-name> \
--statement-id apigateway-invoke-permission \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-2:<account-id>:<api-id>/*/*"

Note the pattern ends with /*/* (stage and route) rather than /*/*/*. For HTTP APIs, the ARN structure differs slightly from REST APIs.

Additionally, enable access logging on your HTTP API stage to capture the $context.integrationErrorMessage variable. This will show you the exact error API Gateway encounters when attempting to invoke your Lambda function. Configure logging with a format that includes:

$context.integrationErrorMessage
$context.error.message
$context.error.responseType

Send the logs to a CloudWatch log group, make another request, and check the logs. The integration error message should reveal whether this is indeed a permission denial or another issue preventing invocation.

If the logs confirm a permission error, remove all existing Lambda permissions for API Gateway and add a fresh one with the corrected ARN pattern. Sometimes stale or conflicting permission statements can cause unexpected behavior even when the policy JSON looks correct.
Sources
Troubleshooting issues with HTTP API Lambda integrations - Amazon API Gateway
Invoking a Lambda function using an Amazon API Gateway endpoint - AWS Lambda

answered a month ago

AWS
EXPERT

reviewed a month ago

EXPERT

reviewed a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.