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

  1. Runtime Version Mismatch in serverless.yml or Console:

    • Diagnosis: In your serverless.yml (or equivalent CloudFormation/Terraform), check the runtime property 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 runtime property to a supported version. For Node.js, this would be something like nodejs18.x or nodejs20.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.
  2. 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_FOUND or specific version errors.
    • Fix: Update your project’s dependencies to versions compatible with the new runtime. For Node.js, this typically means running npm install or yarn install after cleaning your node_modules directory and updating your package.json to 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.
  3. 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_modules and that path is now different or unnecessary in nodejs18.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.
  4. Custom Runtime Configuration:

    • Diagnosis: If you’re using a custom runtime (e.g., specifying provided.al2 or 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 your bootstrap file 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 your FROM statement 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.
  5. 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.
  6. 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.

Want structured learning?

Take the full Lambda course →