AWS Lambda Function Failed to Start: Fix ImportModuleError, HandlerNotFound, ExitError and InvalidEntrypoint
If your Lambda function returns an error before any of your code runs, you have a startup failure, not a runtime failure. This is a different category of problem with its own error codes and fixes. This page covers every major startup failure: Runtime.ImportModuleError, Runtime.HandlerNotFound, Runtime.ExitError, and Runtime.InvalidEntrypoint, plus the scenarios that don’t produce a named error code but still prevent your function from starting.
These failures happen during Lambda’s initialization phase, before your handler function is called. Once you know which error you’re dealing with, the fix is usually straightforward. The diagnosis table below is the fastest way to get there.
Simple explanation
When you invoke a Lambda function, AWS has to do several things before it calls your code. It starts a container, loads the runtime (Python interpreter, Node.js engine, etc.), finds your deployment package or container image, imports your code, and then calls your handler function.
Think of it like a car that won’t start versus one that breaks down mid-journey. Both are broken, but the diagnosis is completely different. A startup failure means the engine never turned over. You’re not debugging what happened during the drive — you’re checking whether the car can move at all.
A startup failure means something in that chain broke before the handler was called. Your handler never ran. Lambda reports one of the named error types listed below, or times out during initialization.
A runtime failure is different: Lambda started successfully, your handler ran, and then something failed inside it. An unhandled exception, a timeout waiting for a database, an out-of-memory crash. Those are covered on the Debugging Lambda Failures page.
If you’re not sure which kind you have, check the error type in the response or CloudWatch Logs. Startup failures always report errors before the REPORT line appears, or never produce one at all.
How Lambda startup works
Understanding the startup sequence tells you exactly where to look when it breaks.
- Container start: Lambda picks an available execution environment or creates a new one (cold start). For container image Lambdas, it pulls the image from Amazon ECR.
- Runtime load: Lambda starts the language runtime (Python, Node.js, Java, etc.) inside the container.
- Layer loading: any Lambda Layers attached to the function are mounted at
/opt/in the filesystem. - Module import: Lambda imports the file named in your handler config. For Python
handler.lambda_handler, it importshandler.py. All top-level code in that file runs at this point. - Handler resolution: Lambda finds the specific function named in your handler config (
lambda_handlerin the Python example) and confirms it exists. - Init code execution: any code at module scope runs: global variable assignments, SDK client instantiation, database connection setup.
- Handler invocation: finally, Lambda calls your handler function with the event and context.
Startup failures happen at steps 2 through 6. If Lambda cannot complete all of these, your handler never gets called.
How to diagnose the error fast
Find the error type in the invocation response or in CloudWatch Logs for your function (/aws/lambda/{function-name}), then match it to the table below.
| Error / symptom | What it usually means | First thing to check | Typical fix |
|---|---|---|---|
Runtime.ImportModuleError | Lambda can’t import your handler file | Is the missing package bundled in your zip? | Add the missing library to your deployment package |
Runtime.HandlerNotFound | Module loaded but the named function wasn’t found | Does the handler string match the actual function name exactly? | Update the handler config or rename the function |
Runtime.ExitError | Process started then crashed immediately | Is there top-level code that can throw? | Move risky init code inside the handler |
Runtime.InvalidEntrypoint | Container ENTRYPOINT/CMD doesn’t invoke the Lambda RIC | Check Dockerfile ENTRYPOINT and CMD | Use a Lambda base image or install awslambdaric |
| Works locally, fails in Lambda | Environment difference | Are all dependencies bundled? Is the runtime version the same? | Bundle dependencies, match runtime version and architecture |
| Fails only after attaching to a VPC | Init-time outbound network call failing | Does init code call an external service? | Add a NAT gateway or VPC endpoint, or move the call inside the handler |
| Container starts locally but not in Lambda | Image built for wrong platform or wrong RIC config | Check image architecture and ENTRYPOINT | Rebuild with --platform linux/amd64 and correct ENTRYPOINT |
Match the first column to what you see in the response JSON or logs, then jump to the corresponding section below.
When to use this page
Use this page if your function fails immediately on invocation with one of the error types above, or if you see the function time out during initialization (cold start timeout) rather than during handler execution.
If your function starts successfully but then fails — a timeout, an unhandled exception mid-execution, an out-of-memory error — that is a runtime failure, not a startup failure. See Debugging Lambda Failures for those.
If you’re just getting started with Lambda and haven’t deployed a function yet, Deploying Your First Lambda Function covers the full deployment process and common first-time mistakes.
Missing dependencies or wrong zip structure
The most common Lambda startup failure is a missing library. When you develop locally, libraries live in your virtual environment. The Lambda execution environment only contains what you include in your deployment package, plus a small set of pre-installed AWS SDK libraries.
The golden rule: all your code and its dependencies must be at the root of the zip file, not inside a subdirectory. This catches the majority of “works on my machine” startup failures.
For Python:
# Wrong: zipping only your source file
zip function.zip handler.py
# Right: install dependencies into the package root first
pip install requests -t ./package
cp handler.py ./package/
cd package && zip -r ../function.zip .With a requirements.txt:
pip install -r requirements.txt -t ./package
cp handler.py ./package/
cd package && zip -r ../function.zip .For Node.js:
npm install --production
zip -r function.zip . -x "*.git*"The node_modules/ directory must be at the root of the zip alongside your handler file.
Lambda Layers let you separate dependencies from your function code. A layer is a zip that Lambda mounts at /opt/ in the execution environment. They’re useful for sharing dependencies across functions, but they don’t remove the requirement that the layer itself is structured correctly.
Note: Python Lambda runtimes include boto3 pre-installed, so you don’t need to bundle it for basic AWS SDK calls. However, the pre-installed version is managed by AWS and may lag the latest release. If you need a specific boto3 version, bundle it explicitly.
Wrong handler name or wrong file path
Lambda locates your function using the handler string you configured. The format is filename.function_name for Python and filename.functionName for Node.js, without the file extension.
Python examples:
| File | Function | Correct handler string |
|---|---|---|
handler.py | lambda_handler | handler.lambda_handler |
app.py | main | app.main |
src/handler.py | lambda_handler | Won’t work: file must be at zip root |
Node.js examples:
| File | Export | Correct handler string |
|---|---|---|
index.js | exports.handler | index.handler |
app.js | exports.processEvent | app.processEvent |
The three most common mistakes:
- The file is named
app.pybut the handler is set tohandler.lambda_handler - The function is named
mainbut the handler expectslambda_handler - The handler file is in a subdirectory in the zip (e.g.
src/handler.py), which Lambda cannot find
To check and fix your handler using the AWS CLI:
# Check current handler configuration
aws lambda get-function-configuration \
--function-name my-function \
--query 'Handler'
# Update the handler string
aws lambda update-function-configuration \
--function-name my-function \
--handler app.lambda_handlerRuntime version or architecture mismatch
Runtime version: code that uses syntax or features from a newer Python or Node.js version will fail on an older Lambda runtime. For example, using Python 3.10 match statements on a Python 3.9 Lambda produces a SyntaxError at import time, which Lambda reports as Runtime.ImportModuleError.
# Check what runtime your function is configured to use
aws lambda get-function-configuration \
--function-name my-function \
--query 'Runtime'
# Update to a newer runtime
aws lambda update-function-configuration \
--function-name my-function \
--runtime python3.12Architecture mismatch: if you build a deployment package on an arm64 machine (Apple Silicon) and deploy to an x86_64 Lambda, compiled extensions (C libraries, Rust modules, packages with C bindings) will fail with import errors. The pure-Python parts of your code will work, but anything that compiles to native code will not.
Build your deployment package on the same architecture as your Lambda, or use Docker with the correct platform flag:
# Build for x86_64 Lambda even on Apple Silicon
docker run --platform linux/amd64 \
-v "$PWD":/var/task \
public.ecr.aws/lambda/python:3.12 \
pip install -r requirements.txt -t ./packageThen confirm the Lambda architecture setting:
aws lambda get-function-configuration \
--function-name my-function \
--query 'Architectures'Init code crashes before the handler runs
Think of top-level code like the lobby of a building. Everyone passes through it on the way in. If the lobby is on fire, nobody gets upstairs — not the first visitor, not the thousandth. When Lambda imports your file, all top-level code runs once, before any invocation. If it throws, the function never starts.
This includes:
- Global variable assignments
- SDK client creation (
boto3.client(...),boto3.resource(...)) - Database connections
- Secret or config fetching
- Any code at module scope
If any of this throws an exception, Lambda reports Runtime.ExitError. The handler was never reached.
Dangerous pattern: calling external services at module load time is the most common cause of Runtime.ExitError. A missing environment variable, a failed network call, or a permissions error in your init code will crash the function for every invocation until it’s fixed.
What this looks like in code:
import os
import psycopg2
# This line runs when Lambda loads the module:
conn = psycopg2.connect(os.environ["DB_HOST"]) # crashes if DB_HOST is not set
def lambda_handler(event, context):
...The fix: use lazy initialization. Connect only on the first real invocation, then reuse the connection on warm invocations:
import os
import psycopg2
_conn = None # safe: nothing happens at module load
def get_connection():
global _conn
if _conn is None:
_conn = psycopg2.connect(os.environ["DB_HOST"])
return _conn
def lambda_handler(event, context):
conn = get_connection() # connects on first invocation, reuses afterward
...The same applies to secrets fetching. If your init code calls AWS Secrets Manager at module load time and that call fails (wrong permissions, network unavailable), Lambda reports a startup failure. Fetch secrets inside the handler, or use the lazy initialization pattern above.
Lambda layer conflicts
Lambda Layers are mounted in order at /opt/. Your deployment package at /var/task/ takes precedence over layers. If two layers include different versions of the same library, which version is loaded depends on mount order, and the result can be an incompatible version causing a startup failure.
If your function worked and then started failing after you added or updated a layer, a layer conflict is the likely cause.
Debug steps:
- Remove layers one at a time to identify which one causes the failure.
- Check if the same library exists in both your deployment package and a layer. The deployment package always wins.
- Pin dependency versions to exact versions in both your deployment package and your layers so you know exactly what’s being loaded.
# List current layers attached to a function
aws lambda get-function-configuration \
--function-name my-function \
--query 'Layers'VPC and network-related startup failures
When a Lambda function is inside a VPC, it operates in a private subnet. Private subnets have no direct internet access by default.
Common misconception: being inside a VPC does not itself cause a startup failure. The problem is init-time outbound network calls. If your initialization code tries to reach the internet from a private subnet with no route out, Lambda times out during startup. The function appears to hang rather than fail with a named error.
If your initialization code tries to call an external API, fetch a configuration file, or connect to an AWS service via its public endpoint, it will fail silently in a private subnet. The failure appears as a timeout during cold start, not as a named startup error.
Check if your Lambda is VPC-attached:
aws lambda get-function-configuration \
--function-name my-function \
--query 'VpcConfig'If it shows subnets and security groups, the function is inside a VPC.
Fixes:
- Add a NAT gateway in the VPC to give private subnets outbound internet access
- Use VPC endpoints for AWS services (S3, DynamoDB, Secrets Manager, etc.) to avoid the internet path entirely
- Move the network-dependent call inside the handler rather than in top-level init code
- Remove the Lambda from the VPC if it doesn’t actually need to access VPC resources
Cold start latency in VPC functions is not itself a failure. Lambda has handled ENI creation efficiently since 2019. The issue is always about outbound connectivity being blocked.
Container image Lambda failures
Container image Lambdas have their own startup failure patterns on top of the standard ones.
Wrong ENTRYPOINT or CMD (Runtime.InvalidEntrypoint)
Lambda expects the container to run the Lambda Runtime Interface Client (RIC) as its entrypoint. When using the official Lambda base images, this is already set up correctly:
FROM public.ecr.aws/lambda/python:3.12
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY handler.py .
CMD ["handler.lambda_handler"]If you use a non-Lambda base image (e.g. python:3.12), you must install the RIC and configure the entrypoint yourself:
FROM python:3.12
RUN pip install awslambdaric
COPY handler.py .
ENTRYPOINT ["python", "-m", "awslambdaric"]
CMD ["handler.lambda_handler"]Image not in ECR in the same region
Lambda pulls container images from Amazon ECR. The ECR repository must be in the same AWS region as your Lambda function. Cross-region image references are not supported.
Missing ECR pull permissions
The Lambda service must be able to pull from the ECR repository. If the ECR repository policy doesn’t allow the Lambda service principal, the function can’t start.
# Verify the image URI your Lambda is using
aws lambda get-function \
--function-name my-function \
--query 'Code.ImageUri'Architecture mismatch for container images
The same arm64 vs x86_64 issue applies to container images. If you build the image on Apple Silicon and push it to ECR without specifying --platform linux/amd64, it won’t run on an x86_64 Lambda.
docker build --platform linux/amd64 -t my-lambda-image .Startup failure vs runtime failure
Choosing the wrong troubleshooting path wastes time. Here’s how to tell which you’re dealing with:
| Failure type | When it happens | What you see in logs | Page to use |
|---|---|---|---|
| Startup failure | Before handler runs | Named error type (ImportModuleError, HandlerNotFound, etc.), no REPORT line or one with very short duration | This page |
| Timeout | Handler runs too long | Task timed out after X seconds in logs, Duration equals configured timeout in REPORT | Debugging Lambda Failures |
| Out of memory | Handler uses too much RAM | Max Memory Used equals Memory Size in REPORT line | Debugging Lambda Failures |
| Unhandled exception | Inside handler during invocation | Stack trace in logs, Duration well under timeout | Debugging Lambda Failures |
If you’re unsure whether to use Lambda at all for your use case, Choosing Between EC2, Lambda and Containers explains when each service fits.
Step-by-step troubleshooting checklist
Follow this sequence for any Lambda startup failure:
- Identify the error type. Check the invocation response JSON for
errorType, or search CloudWatch Logs for the function’s log group (/aws/lambda/{function-name}). - Check the handler string. Confirm
filename.function_namematches exactly: correct file, correct function name, no subdirectory path in the zip. - Inspect the deployment package. Unzip locally and verify all dependencies are at the root, not in a subdirectory.
- Check runtime and architecture. Confirm the Lambda runtime version matches what you developed against, and that the architecture (x86_64 vs arm64) matches any compiled extensions.
- Audit layer contents. If layers are attached, remove them one at a time to identify conflicts. Check for duplicate library versions.
- Check VPC and network settings. If the function is VPC-attached, confirm init code doesn’t make outbound network calls that would fail in a private subnet.
- Test locally. Use SAM CLI to invoke the function with the Lambda execution environment:
sam local invoke MyFunction --event test-event.json - For container images. Confirm ENTRYPOINT/CMD points to the RIC, the image is in ECR in the same region, and the image architecture matches the Lambda configuration.
- Redeploy and verify. After making changes, deploy and invoke the function. Check Monitoring Lambda metrics to confirm the error rate drops to zero.
Common mistakes
- Zipping only the source file without dependencies.
zip function.zip handler.pyalways fails unless all dependencies are bundled in the same zip at the root level. - Handler string pointing to the wrong file or function name. It’s case-sensitive and must match exactly. Python uses
filename.function_namewithout the.pyextension. - Building on arm64 (Apple Silicon) for an x86_64 Lambda. Compiled C extensions, Rust modules, and native libraries won’t run across architectures. Use
—platform linux/amd64in Docker builds or a matching build environment. - Top-level code that calls external services at import time. If module initialization tries to connect to a database or API and fails, Lambda reports a startup error before any invocation completes. Use lazy initialization inside the handler.
- Assuming layers automatically fix missing dependencies. Layers must be structured correctly (dependencies at the right path inside the layer zip) and must not conflict with versions in the deployment package.
Summary
- Startup failures happen before your handler runs. The four main error types are
Runtime.ImportModuleError,Runtime.HandlerNotFound,Runtime.ExitError, andRuntime.InvalidEntrypoint. - Bundle all dependencies into your deployment zip at the root level. Lambda only has what you give it.
- The handler string format is
filename.function_namefor Python (no.py) and must match the actual file and export exactly. - Top-level init code that crashes before the handler causes
Runtime.ExitError. Move risky calls inside the handler or use lazy initialization. - VPC-attached Lambdas with init-time outbound network calls will fail if there’s no NAT gateway or VPC endpoint. The failure looks like a cold start timeout.
- For container image Lambdas: use a Lambda base image or install
awslambdaric, keep the image in ECR in the same region, and match the image architecture to the Lambda configuration.
Frequently asked questions
What is the difference between Runtime.ImportModuleError and Runtime.ExitError?
Runtime.ImportModuleError means the Lambda runtime could not load your handler module at all, usually because of a missing dependency or wrong handler path. Runtime.ExitError means the process loaded and started, but crashed before returning a response, often because of a failure in top-level initialization code such as a failed database connection or missing environment variable.
Why does my Lambda work locally but fail in AWS?
The Lambda execution environment is not your local machine. Common causes: different Python or Node.js version, missing packages that exist on your machine but not in the deployment package, architecture mismatch (arm64 vs x86_64 for compiled dependencies), or environment variables set locally but not configured in Lambda.
Does Lambda include boto3 automatically?
Python Lambda runtimes include boto3 pre-installed, but the included version may lag behind the latest release. If your code uses a feature from a newer boto3 version, bundle boto3 in your deployment package to pin the version you need.
Why does a Lambda fail only after I attach it to a VPC?
A Lambda in a VPC loses direct internet access. If your initialization code calls an external API, fetches a secret from a public endpoint, or connects to an AWS service via its public endpoint, those calls will fail in a private subnet without a NAT gateway or VPC endpoint. The failure appears as a timeout during startup, not a named startup error.
What does Runtime.InvalidEntrypoint mean for container image Lambdas?
Runtime.InvalidEntrypoint means the Docker ENTRYPOINT or CMD in your container image does not correctly point to the Lambda Runtime Interface Client (RIC). Lambda expects the container to run the RIC as its entrypoint. If you use a non-Lambda base image, you must install awslambdaric and set ENTRYPOINT to invoke it before your handler.