The Error
You deploy a Lambda function, trigger it, and immediately get this in CloudWatch Logs:
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'requests'
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 1, in <module>
import requests
Lambda runs in a minimal execution environment with no third-party packages pre-installed. If your code calls import requests, import pandas, or anything outside the Python standard library, you need to ship those packages yourself. Even boto3 has a built-in version that can be outdated โ if you need a specific release, bundle it too.
Why This Happens
Whether you upload a .zip file or use the console's inline editor, Lambda only sees the files you explicitly include. There's no connection to your local machine. The packages you installed with pip live in your virtual environment โ they never made it into the deployment artifact, so Lambda has no idea they exist.
Fix Option 1 โ Bundle Dependencies Into Your Deployment Package (Quickest)
The fastest solution: install packages directly into your project folder, then zip everything together.
Step 1 โ Create a clean project folder
mkdir my_lambda
cd my_lambda
Step 2 โ Install dependencies into the project folder
pip install requests -t .
The -t . flag tells pip to install into the current directory instead of your global Python environment. Repeat this for every package your function needs. For requests==2.31.0, you'd end up with roughly 300KB of files dropped right into the folder.
Step 3 โ Add your function file
# lambda_function.py
import requests
def lambda_handler(event, context):
response = requests.get("https://httpbin.org/get")
return {
"statusCode": response.status_code,
"body": response.text
}
Step 4 โ Zip everything up
zip -r function.zip .
Critical detail: lambda_function.py must sit at the root of the zip, not inside a subfolder. Lambda looks for the handler at the top level and won't search subdirectories.
Step 5 โ Deploy the zip
aws lambda update-function-code \
--function-name my-function-name \
--zip-file fileb://function.zip
Fix Option 2 โ Use a Lambda Layer (Better for Reuse)
Got five Lambda functions that all use requests and boto3? Bundling the same packages into five separate zips wastes space and makes updates painful. A Lambda Layer lets you package dependencies once and attach them to any function that needs them โ keeping each deployment zip lean (sometimes under 10KB) and your dependency updates centralized.
Step 1 โ Build the layer directory structure
Python layers must follow a specific folder layout. Lambda looks for packages under python/ โ any other name and it won't load them.
mkdir -p layer/python
pip install requests -t layer/python/
Step 2 โ Zip the layer
cd layer
zip -r ../requests_layer.zip python/
cd ..
Step 3 โ Publish the layer to AWS
aws lambda publish-layer-version \
--layer-name requests-layer \
--zip-file fileb://requests_layer.zip \
--compatible-runtimes python3.9 python3.10 python3.11
Copy the LayerVersionArn from the output. It looks something like arn:aws:lambda:us-east-1:123456789012:layer:requests-layer:1 โ you'll need it in the next step.
Step 4 โ Attach the layer to your function
aws lambda update-function-configuration \
--function-name my-function-name \
--layers arn:aws:lambda:us-east-1:123456789012:layer:requests-layer:1
Swap in the ARN you copied from Step 3.
Step 5 โ Deploy your function code (without bundled deps)
# Only zip your function file โ no packages needed
zip function.zip lambda_function.py
aws lambda update-function-code \
--function-name my-function-name \
--zip-file fileb://function.zip
Fix Option 3 โ Use AWS SAM or CDK (For CI/CD Pipelines)
Working on a team project with a proper deployment pipeline? Skip the manual zipping entirely. Add a requirements.txt and SAM handles dependency bundling automatically during sam build.
# requirements.txt
requests==2.31.0
# template.yaml (relevant section)
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: lambda_function.lambda_handler
Runtime: python3.11
CodeUri: ./src
Layers: [] # SAM installs from requirements.txt automatically
sam build
sam deploy
Verify the Fix
Once deployed, invoke the function and check the response:
aws lambda invoke \
--function-name my-function-name \
--payload '{}' \
response.json
cat response.json
A clean run returns:
{"statusCode": 200, "body": "{...}"}
Still seeing Runtime.ImportModuleError? Stream the latest logs directly:
aws logs tail /aws/lambda/my-function-name --follow
Before you even re-deploy, confirm the package actually landed inside the zip:
unzip -l function.zip | grep requests
You should see requests/__init__.py at the archive root. If that line is missing, the package never made it in.
Common Mistakes That Keep the Error Coming Back
- Wrong Python version: Running
pip installwith Python 3.11 but deploying to a Python 3.9 runtime breaks compiled packages likenumpyorcryptography. Match your local Python version to the Lambda runtime exactly. - Installing into the wrong directory: Running
pip install requestswithout-t .dumps the packages into your system Python, not your project folder. They won't end up in the zip. - Nested zip structure: Zipping from the parent directory creates a structure like
my_lambda/lambda_function.py. Lambda can't find the handler that way. Alwayscdinto the project folder before zipping. - Layer folder name mismatch: Python layer packages must live under
python/inside the zip. Use any other folder name and Lambda silently ignores the entire layer. - Forgetting to attach the layer: Publishing a layer doesn't wire it up to any function. The
update-function-configuration --layersstep is mandatory โ easy to skip, hard to spot. - Platform-specific wheels: Packages with C extensions (like
numpyorPillow) must be compiled for Amazon Linux 2. Build them inside a matching Docker container:docker run --rm -v $(pwd):/var/task public.ecr.aws/lambda/python:3.11 pip install requests -t /var/task/
Quick Reference โ Which Fix to Use
- Single function, simple deps: Bundle with
pip install -t .and zip. - Multiple functions sharing deps: Use a Lambda Layer.
- Team project with CI/CD: Use SAM or CDK with
requirements.txt. - Large or compiled packages (numpy, pandas, Pillow): Build with Docker matching the Lambda runtime.

