Fix: AWS Lambda Unable to import module / Runtime.ImportModuleError
Quick Answer
How to fix the AWS Lambda Runtime.ImportModuleError and Unable to import module error caused by wrong handler paths, missing dependencies, layer issues, and packaging problems.
The Error
You deploy a Lambda function, invoke it, and get this in CloudWatch:
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'lambda_function'Or a variation like:
[ERROR] Runtime.ImportModuleError: Unable to import module 'handler': No module named 'handler'[ERROR] Runtime.ImportModuleError: Unable to import module 'app': No module named 'requests'The function never executes. Every invocation fails immediately with the same import error. This is one of the most common Lambda deployment errors, and it almost always comes down to how your code is packaged or how the handler is configured.
Why This Happens
When Lambda starts your function, the runtime tries to import the Python module specified in the handler setting. The handler follows the format module_name.function_name. For example, lambda_function.lambda_handler means Lambda will look for a file called lambda_function.py and call the lambda_handler function inside it.
The Runtime.ImportModuleError fires when Python’s import system cannot find or load that module. The root causes fall into several categories:
- Wrong handler path — the handler setting does not match the actual file location inside the deployment package.
- Missing dependencies — your code imports a third-party library that is not included in the deployment zip.
- Bad zip structure — the files are nested inside a subdirectory instead of sitting at the root of the zip.
- Runtime mismatch — a dependency was built for a different Python version or CPU architecture.
- Layer misconfiguration — a Lambda layer exists but its contents are not placed in the correct directory structure.
- Native binary incompatibility — C extension modules compiled on macOS or Windows will not work in the Lambda Linux environment.
Each fix below targets a specific cause. Start with Fix 1 and work down — the most common causes are listed first.
Fix 1: Correct the Handler Path
The handler configuration is the single most common cause of this error. Open your Lambda function in the AWS Console, go to Runtime settings, and check the Handler field.
The format is:
<module_path>.<function_name>If your file is lambda_function.py at the root of your zip with a function called lambda_handler, the handler must be:
lambda_function.lambda_handlerIf your file is inside a subdirectory, use dot notation. For a file at src/handlers/process.py with a function handle:
src.handlers.process.handleCommon mistakes:
- Including the
.pyextension:lambda_function.py.lambda_handler— wrong. - Using slashes instead of dots:
src/handlers/process.handle— wrong. - Mismatched case: Python file names are case-sensitive in Lambda’s Linux environment, even if they worked on your Windows or macOS machine.
Verify the handler matches your actual file structure by downloading the deployment package and inspecting it:
aws lambda get-function --function-name my-function --query 'Code.Location' --output text | xargs curl -o function.zip
unzip -l function.zipCheck that the file referenced by the handler actually exists at the expected path inside the zip.
Pro Tip: If you renamed your handler file or function during refactoring but forgot to update the Lambda handler setting, this error will appear on the next invocation. Always update both the code and the configuration together.
Fix 2: Include Missing Dependencies
If the error message mentions a specific third-party module like No module named 'requests' or No module named 'pandas', the dependency is not in your deployment package.
Lambda does not have pip packages pre-installed (except boto3 and botocore, which are included in the Python runtime). You must bundle every other dependency yourself.
Install dependencies into a local directory and zip everything together:
mkdir package
pip install -r requirements.txt -t package/
cp lambda_function.py package/
cd package
zip -r ../deployment.zip .Then deploy:
aws lambda update-function-code --function-name my-function --zip-file fileb://deployment.zipThe -t flag tells pip to install packages into the specified directory instead of your system Python. This is critical — without it, the packages go into your local site-packages and never make it into the zip.
If you are on Windows or macOS and the package has native extensions (like numpy, pillow, or psycopg2), see Fix 6 for additional steps. The binaries compiled on your machine will not work in Lambda’s Amazon Linux environment.
For packages that are pure Python (no compiled C code), installing with -t and zipping is sufficient regardless of your development OS.
Fix 3: Set Up Lambda Layers Correctly
Lambda layers let you share dependencies across multiple functions, but the directory structure inside the layer zip must follow a specific convention. If it is wrong, Python will not find the modules even though the layer is attached.
For Python, the layer zip must place packages inside:
python/Or more specifically:
python/lib/python3.x/site-packages/Here is the correct way to create a layer:
mkdir -p python
pip install requests boto3 -t python/
zip -r layer.zip python/Then publish the layer:
aws lambda publish-layer-version \
--layer-name my-dependencies \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.11 python3.12Attach it to your function:
aws lambda update-function-configuration \
--function-name my-function \
--layers arn:aws:lambda:us-east-1:123456789:layer:my-dependencies:1Common layer mistakes:
- Putting packages directly in the zip root instead of inside a
python/directory. - Zipping the parent directory so the structure becomes
layer/python/...instead ofpython/.... - Forgetting to attach the layer to the function after publishing it.
- Using a layer built for Python 3.9 with a function running Python 3.12.
To verify your layer structure:
unzip -l layer.zip | head -20You should see paths starting with python/ — not a nested directory above it.
Fix 4: Fix the Zip Package Structure
A subtle but frequent problem: the zip file contains a top-level directory wrapping your code. This happens when you zip the folder itself instead of its contents.
Wrong (creates a nested directory):
zip -r deployment.zip my-project/This produces a zip with structure:
my-project/
lambda_function.py
requirements.txtLambda cannot find lambda_function because it is inside my-project/, not at the root.
Correct (zip the contents):
cd my-project
zip -r ../deployment.zip .This produces:
lambda_function.py
requirements.txtAlways verify the structure before deploying:
unzip -l deployment.zipThe .py file referenced by your handler must appear at the path that matches the handler setting. If the handler is lambda_function.lambda_handler, then lambda_function.py must be at the zip root. If the handler is src.app.handler, then src/app.py must exist at that relative path inside the zip.
If you use a CI/CD pipeline that creates the zip, add a verification step that lists the zip contents and checks for the expected file. This catches packaging mistakes before they reach production.
Fix 5: Fix Python Runtime Version Mismatch
If your function uses a feature or syntax only available in a newer Python version, or if a dependency requires a specific Python version, a version mismatch can cause import failures.
Check your function’s runtime:
aws lambda get-function-configuration --function-name my-function --query 'Runtime'Common scenarios:
- Using match/case statements (Python 3.10+) on a Lambda running Python 3.9. The syntax error manifests as an import error because the module fails to compile.
- Using
tomllib(Python 3.11+) on Python 3.9 or 3.10. - Dependencies compiled for Python 3.12 deployed to a function running Python 3.9. Compiled
.sofiles are version-specific.
Check what Python version your dependencies were built for:
unzip -l deployment.zip | grep ".so"If you see paths like cpython-312-x86_64-linux-gnu.so, those files only work with Python 3.12 on x86_64.
To fix this, make sure you install dependencies using the same Python version as your Lambda runtime:
python3.12 -m pip install -r requirements.txt -t package/Or use a Docker container that matches the Lambda environment:
docker run --rm -v $(pwd):/var/task public.ecr.aws/sam/build-python3.12:latest \
pip install -r requirements.txt -t python/If you recently upgraded your Lambda runtime (e.g., from Python 3.9 to 3.12), rebuild all dependencies from scratch. Do not reuse the old deployment package — the compiled extensions are not forward-compatible.
If you are encountering import issues related to other Python environments, you might find this guide on Python module not found errors helpful for understanding how Python resolves imports.
Fix 6: Fix Native Binary Dependencies
Some Python packages include C extensions — compiled .so files that must match both the operating system and CPU architecture of the Lambda execution environment. If you install these packages on macOS or Windows, the compiled binaries will not work on Lambda’s Amazon Linux.
Affected packages include numpy, pandas, scipy, pillow, psycopg2, cryptography, lxml, and many others.
Symptoms: The error message might say Unable to import module or sometimes cannot import name or undefined symbol.
Build dependencies inside a Docker container that matches the Lambda environment:
docker run --rm -v $(pwd):/var/task public.ecr.aws/sam/build-python3.12:latest \
pip install -r requirements.txt -t package/Architecture matters too. Lambda functions run on either x86_64 or arm64 (Graviton). If your function uses arm64 but your dependencies were compiled for x86_64, the import will fail.
Check your function’s architecture:
aws lambda get-function-configuration --function-name my-function --query 'Architectures'Then build for the correct architecture:
# For arm64 Lambda functions
docker run --rm --platform linux/arm64 -v $(pwd):/var/task \
public.ecr.aws/sam/build-python3.12:latest \
pip install -r requirements.txt -t package/Common Mistake: Using
pip install psycopg2instead ofpip install psycopg2-binary. The non-binary version tries to compile from source and requireslibpq-devheaders, which are not present in Lambda. Use the binary variant or build inside the SAM Docker image with the required system libraries.
For psycopg2 specifically, an even better option is aws-psycopg2, a pre-compiled version built for Lambda:
pip install aws-psycopg2 -t package/Some packages provide pre-built Lambda-compatible wheels. Check the package documentation before building from source. This can save significant build time, especially for heavy scientific packages.
If you are running into credential-related errors while your Lambda tries to access AWS services, see how to fix AWS credential configuration issues.
Fix 7: Fix SAM, CDK, and Serverless Framework Packaging
If you deploy with AWS SAM, CDK, or the Serverless Framework, the packaging step might silently exclude your dependencies or misconfigure the handler path.
AWS SAM
In template.yaml, verify the Handler and CodeUri are correct:
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
Runtime: python3.12
CodeUri: src/If CodeUri points to src/, then app.py must exist inside the src/ directory. SAM zips the contents of CodeUri — the directory itself is not included.
To include dependencies, add a requirements.txt inside the CodeUri directory. SAM automatically runs pip install during sam build:
sam build
sam deploy --guidedIf sam build is not picking up your dependencies, check that requirements.txt is in the same directory as your code (the CodeUri path).
AWS CDK
With CDK’s PythonFunction construct, dependencies are bundled automatically from a requirements.txt in the entry directory:
from aws_cdk.aws_lambda_python_alpha import PythonFunction
PythonFunction(self, "MyFunction",
entry="lambda/",
runtime=Runtime.PYTHON_3_12,
index="app.py",
handler="lambda_handler",
)Make sure requirements.txt exists at lambda/requirements.txt. CDK uses Docker to install dependencies, so Docker must be running on your machine during cdk deploy.
If you use the standard Function construct instead of PythonFunction, you must handle dependency bundling yourself — CDK will not install pip packages automatically.
Serverless Framework
In serverless.yml:
functions:
process:
handler: handler.process
runtime: python3.12
package:
include:
- handler.py
- lib/**Use the serverless-python-requirements plugin to handle dependencies:
npm install serverless-python-requirements --save-devplugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: trueThe dockerizePip: true setting builds packages inside a Lambda-like Docker container, which solves native binary issues (Fix 6) automatically.
A common deployment issue is when your function runs but gets terminated for a different reason. If you are seeing timeout errors alongside import errors, check how to fix Lambda timeout issues to rule out configuration problems.
Fix 8: Fix Container Image Lambda Imports
If your Lambda uses a container image instead of a zip deployment, the import error usually means the image’s working directory or entrypoint is misconfigured.
Your Dockerfile must set the CMD to the handler in the same format as the handler setting:
FROM public.ecr.aws/lambda/python:3.12
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["app.lambda_handler"]Common issues with container image Lambdas:
Wrong WORKDIR. The Lambda base image expects code in /var/task. If you copy files elsewhere, the runtime cannot find them:
# Wrong — files are in /app, but Lambda looks in /var/task
WORKDIR /app
COPY . .
# Correct — use the default WORKDIR or copy to /var/task
COPY app.py /var/task/Missing dependencies in the image. Unlike zip deployments, there is no layer mechanism. All dependencies must be installed in the image:
COPY requirements.txt .
RUN pip install -r requirements.txt --target /var/taskMulti-stage build losing packages. If you use a multi-stage build, make sure you copy the installed packages to the final stage:
FROM public.ecr.aws/lambda/python:3.12 AS builder
COPY requirements.txt .
RUN pip install -r requirements.txt -t /opt/python/
FROM public.ecr.aws/lambda/python:3.12
COPY --from=builder /opt/python/ /var/task/
COPY app.py /var/task/
CMD ["app.lambda_handler"]Test your container image locally before pushing to ECR:
docker build -t my-lambda .
docker run -p 9000:8080 my-lambda
# In another terminal:
curl -X POST "http://localhost:9000/2015-03-31/functions/function/invocations" \
-d '{"test": "event"}'If the local test returns a successful response, the import is working correctly. If it fails locally, fix the Dockerfile before deploying.
For container images, you can also use the Runtime Interface Emulator (RIE) to debug import issues. The emulator replicates the Lambda runtime locally and shows the exact same error messages you would see in CloudWatch.
Still Not Working?
If none of the fixes above resolved the error, try these less common causes:
Check for circular imports. If module A imports module B and module B imports module A, Python may fail to resolve the import chain. This shows up as ImportModuleError even though all files are present in the package. Restructure your code to break the cycle, or use lazy imports inside functions. See how to fix circular import errors in Python for a detailed walkthrough.
Check file permissions inside the zip. On rare occasions, files in the zip lack read permissions. Lambda runs as a non-root user (sbx_userXXXX) and needs read access:
chmod 644 *.py
zip -r deployment.zip .Check for __init__.py files. If your handler is in a package (subdirectory), every directory in the path must contain an __init__.py file for Python to treat it as a package. For handler src.handlers.process.handle:
src/__init__.py
src/handlers/__init__.py
src/handlers/process.pyCheck the deployment package size. Lambda has a 250 MB limit for unzipped deployment packages (50 MB zipped for direct upload). If your package exceeds this, the deployment might silently truncate or fail. Use layers to split large dependencies, or switch to a container image deployment which supports up to 10 GB.
Check CloudWatch logs for the full traceback. The Runtime.ImportModuleError message sometimes hides a deeper error. Look at the full stack trace in CloudWatch Logs — it might reveal a SyntaxError, AttributeError, or a missing system library that tells you exactly what went wrong.
Verify IAM permissions. While rare, if your Lambda function tries to import a module that immediately makes an AWS API call at import time (e.g., in module-level code), an IAM access denied error can manifest as an import failure. Move AWS API calls out of module-level code and into the handler function.
Use Lambda’s built-in code editor for a quick test. If you are unsure whether the issue is in your code or packaging, paste a minimal version of your handler directly into the Lambda console’s inline editor. If that works, the problem is in your deployment package — not your code.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Python TypeError: unhashable type: 'list'
Learn why Python raises TypeError unhashable type list, dict, or set and how to fix it when using dictionary keys, sets, groupby, dataclasses, and custom classes.
Fix: AWS CloudFormation stack in ROLLBACK_COMPLETE or CREATE_FAILED state
How to fix AWS CloudFormation ROLLBACK_COMPLETE and CREATE_FAILED errors caused by IAM permissions, resource limits, invalid parameters, and dependency failures.
Fix: Django Forbidden (403) CSRF verification failed
How to fix Django 403 CSRF verification failed error caused by missing CSRF tokens, AJAX requests, cross-origin issues, HTTPS misconfig, and session problems.
Fix: FastAPI 422 Unprocessable Entity (validation error)
How to fix FastAPI 422 Unprocessable Entity error caused by wrong request body format, missing fields, type mismatches, query parameter errors, and Pydantic validation.