You’re migrating a Lambda function and hit a wall because the runtime you’re using is deprecated. This means the underlying operating system and language interpreter that your function code runs on is no longer being updated by AWS, posing security risks and preventing new features.
Let’s say you’re moving from nodejs14.x to nodejs18.x.
Common Causes and Fixes
-
Runtime Version Mismatch in
serverless.ymlor Console:- Diagnosis: In your
serverless.yml(or equivalent CloudFormation/Terraform), check theruntimeproperty for your function. If you’re using the AWS console, navigate to your Lambda function, go to "Configuration" -> "General configuration", and check the "Runtime" field. - Fix: Update the
runtimeproperty to a supported version. For Node.js, this would be something likenodejs18.xornodejs20.x.functions: myFunction: handler: handler.hello runtime: nodejs18.x # <-- Change this - Why it works: Lambda needs to know which environment to spin up for your code. If it’s told to use a runtime that no longer exists, it can’t provision the execution environment.
- Diagnosis: In your
-
Dependency Incompatibility:
- Diagnosis: After updating the runtime in your configuration, your deployment might fail, or the function might crash with errors related to missing modules or incompatible versions. Check the Lambda execution logs for
MODULE_NOT_FOUNDor specific version errors. - Fix: Update your project’s dependencies to versions compatible with the new runtime. For Node.js, this typically means running
npm installoryarn installafter cleaning yournode_modulesdirectory and updating yourpackage.jsonto specify compatible versions. For example, if a package was written for Node.js 14 and has issues with Node.js 18, you might need to find a newer version of that package.# Clean old modules rm -rf node_modules # Install fresh with updated dependencies npm install - Why it works: Newer language runtimes often have stricter parsing, different built-in module behaviors, or deprecate APIs used by older libraries. Re-installing dependencies ensures you get versions that have been tested and updated for the target runtime.
- Diagnosis: After updating the runtime in your configuration, your deployment might fail, or the function might crash with errors related to missing modules or incompatible versions. Check the Lambda execution logs for
-
Environment Variable Overrides:
- Diagnosis: Sometimes, environment variables are used to point to specific runtime executables or configurations that are no longer valid in the new runtime. Check your Lambda function’s environment variables for any that might relate to runtime paths or executable names.
- Fix: Remove or update any environment variables that are hardcoding paths or names related to the old runtime. For example, if you had
NODE_PATH=/opt/nodejs/node_modulesand that path is now different or unnecessary innodejs18.x, remove it. - Why it works: Environment variables can override default behaviors. If an old, now-invalid, environment variable is present, it can prevent the new runtime from initializing correctly.
-
Custom Runtime Configuration:
- Diagnosis: If you’re using a custom runtime (e.g., specifying
provided.al2or a Docker image), the base image or the bootstrap script might be referencing components from the old runtime that are no longer present or compatible. Examine yourbootstrapfile or the Dockerfile. - Fix: For
provided.al2, ensure your bootstrap script is compatible with Amazon Linux 2. If you’re using a Docker image, update yourFROMstatement to a newer base image (e.g., a newer Alpine or Ubuntu version) and ensure your bootstrap logic or application entry point is compatible with the new OS and language versions within that image.# Example Dockerfile change # FROM public.ecr.aws/lambda/nodejs:14 # Old FROM public.ecr.aws/lambda/nodejs:18 # New - Why it works: Custom runtimes require you to manage the entire execution environment. When migrating, you need to ensure the entire environment, not just your code, is compatible with the target runtime version and its underlying OS.
- Diagnosis: If you’re using a custom runtime (e.g., specifying
-
Layer Version Incompatibility:
- Diagnosis: If your Lambda function uses Lambda Layers, a layer might contain libraries or executables tied to the old runtime version. Check the ARN of the layers attached to your function.
- Fix: Update the Lambda Layers associated with your function to versions that are compatible with the new runtime. You might need to rebuild your layers or find updated versions from third-party providers.
functions: myFunction: handler: handler.hello runtime: nodejs18.x layers: - arn:aws:lambda:us-east-1:123456789012:layer:my-compatible-layer:2 # <-- Update layer ARN - Why it works: Layers are essentially zipped code that gets mounted into your Lambda’s execution environment. If a layer contains binaries or scripts compiled for an older Node.js version, they won’t work with a newer one.
-
Code-Level Runtime-Specific APIs:
- Diagnosis: Your application code might be directly calling APIs or using syntax that was deprecated or removed in the newer runtime version. This is harder to diagnose automatically and usually surfaces as a runtime error or unexpected behavior.
- Fix: Review your codebase for any direct calls to deprecated functions or syntax that might have changed between runtime versions. For Node.js, consult the official Node.js release notes for breaking changes between your old and new versions (e.g., Node.js 14 to 18).
- Why it works: Language runtimes evolve. Features can be deprecated, removed, or have their behavior altered. Your code needs to adhere to the APIs and syntax supported by the target runtime.
After successfully migrating, the next hurdle you’ll likely face is optimizing the cold start times for your new runtime, as newer runtimes can sometimes have different initialization characteristics.