Debug a Lambda function that fails, times out or is throttled

A ranked checklist for a Lambda function that errors, times out, never runs or is throttled — read the error, read the logs, then check timeout, VPC route, permissions on both sides, state, concurrency and recursion, with the CLI command for each check.

markdownguidev4ZV3P-JR3Cstage: operatetrust: officialservice: lambdainterface: cliLambda not workingTask timed out afterLambda timeout VPCLambda throttledTooManyRequestsExceptionRate ExceededFunctionErrorCloudWatch Logs LambdaRuntime.ImportModuleErrorRuntime.NodejsExitResourceConflictException Pendingrecursive loopreserved concurrency 0

Created 18 Oct 2026 · Modified 23 Oct 2026 · 4 versions

Get the actual error first. Invoke synchronously with --log-type Tail, or read the function's log group, and look the message up in reference/lambda/errors.md. Most failures are one of these: the 3-second default timeout, a VPC function with no route out, a missing permission on the execution role, or a missing permission on the function's own policy.

Step 0: reproduce and read

aws lambda invoke --function-name <fn> --cli-binary-format raw-in-base64-out \
  --payload file://event.json --log-type Tail out.json
cat out.json        # the function's return value, or {"errorType","errorMessage","trace"}
aws logs tail /aws/lambda/<fn> --since 30m --follow
# or search a wider window with Logs Insights: reference/cloudwatch/logs-insights-queries.md

The response's StatusCode is 200 even when the code threw. A function error shows as FunctionError in the response and an error object in out.json. A service error (throttle, missing permission, bad payload size) fails the CLI call itself with an exception name and a 4xx/5xx status. Those are different problems.

If the log group does not exist, the function has never run, or its role cannot write logs (missing AWSLambdaBasicExecutionRole).

Ranked checks

1. Timeout: Task timed out after N.NN seconds

  • Timeout too short. The default is 3 seconds. Raise it with aws lambda update-function-configuration --function-name <fn> --timeout 30 (the maximum is 900).
  • The function waits on a network call that never answers. If the function is attached to a VPC, it has no internet access and no public IP, even in a public subnet. Calls to AWS APIs or the internet hang until the timeout. Fix: private subnets with a route to a NAT gateway, or VPC endpoints for the AWS services it calls (patterns/lambda-in-vpc.md). Check: aws lambda get-function-configuration --function-name <fn> --query VpcConfig.
  • Slow downstream or cold start work. Log timestamps around each call. Set the SDK client's own timeouts below the function timeout so you get an error instead of a silent timeout.

2. Permission denied inside the function

AccessDenied or … is not authorized to perform: <action> from an SDK call means the execution role lacks the action. Add it to the role, not to your user. Find the role with aws lambda get-function-configuration --function-name <fn> --query Role. For S3 objects encrypted with KMS, also kms:Decrypt. To diagnose further: guides/iam/fix-access-denied.md.

3. Another service cannot invoke it

… is not authorized to perform: lambda:InvokeFunction on resource: … means the function's resource-based policy does not allow the caller. That applies to S3, EventBridge, SNS, API Gateway, or another account. Inspect it with aws lambda get-policy --function-name <fn>. Fix with add-permission or a full policy (reference/lambda/permissions.md). For a caller in the same account, an identity policy allowing lambda:InvokeFunction is enough.

4. Code or packaging

SymptomLikely cause
Runtime.ImportModuleError / Cannot find moduleHandler setting does not match the bundled file (index.handler → index.mjs or index.js at the zip root), or a dependency was not bundled. UNVERIFIED exact message text.
Runtime.HandlerNotFoundThe file exists but does not export that name. UNVERIFIED exact message text.
Runtime.NodejsExitThe code called process.exit() or the event loop crashed. Return from the handler instead.
Couldn't find valid bootstrap(s): [/var/task/bootstrap /opt/bootstrap]A custom runtime with no executable bootstrap in the package
Runtime exited with error: signal: killedMemory exhausted. Raise --memory-size. UNVERIFIED exact message text.

5. State and in-flight updates

ResourceConflictException: … The function is currently in the following state: Pending means a create or update is still in progress. Use aws lambda wait function-updated-v2 --function-name <fn> before the next call. A function stuck Inactive or Failed reports why in StateReasonCode: aws lambda get-function-configuration --function-name <fn> --query '[State,StateReason,StateReasonCode,LastUpdateStatus]'. VPC (ENI or subnet) and KMS problems show here.

6. Throttling: TooManyRequestsException (429)

The account's concurrency is a per-Region quota shared by all functions. A function with reserved concurrency cannot exceed it, and reserved concurrency of 0 stops all invocations, sometimes set deliberately to break a loop. Check with aws lambda get-function-concurrency --function-name <fn> and aws lambda get-account-settings. Each function can also only add 1,000 execution environments every 10 seconds, so a sudden burst throttles even below the quota. Asynchronous sources (S3, SNS, EventBridge) retry throttled events. Synchronous callers must retry with backoff.

7. Runs repeatedly or never stops

  • Asynchronous retries. Failed async invocations are retried up to two more times. Make the handler idempotent, and configure a failure destination or dead-letter queue to catch what still fails.
  • Recursive loop. For example, a function that writes to the bucket or queue that triggers it. Lambda detects some loops and stops them (RecursiveInvocationException). To stop one immediately: aws lambda put-function-concurrency --function-name <fn> --reserved-concurrent-executions 0. Then fix the trigger.

8. Payload too big

RequestTooLargeException (413) means the request exceeds the payload limit: 6 MB synchronous, 1 MB asynchronous. A response over 6 MB fails the synchronous invocation. Pass large data through S3 and send a reference.

Environment variables encrypted with a disabled key

KMSDisabledException: Lambda was unable to decrypt the environment variables because the KMS key used is disabled means the customer managed key on the function's environment is disabled. Re-enable the key, or update the function to use another key. The execution role needs kms:Decrypt on the key.

Still stuck

Compare against a minimal handler that only returns { ok: true }, with the same role, VPC and memory. If that fails too, the problem is configuration, not code.

Related: the invoke call and its retries (reference/lambda/invoke.md); runtime deprecation dates and fixed limits (reference/lambda/runtimes-and-limits.md); building and deploying TypeScript (guides/lambda/deploy-function.md).

Read this document as markdown — the same bytes an agent receives.