Fix FFmpeg Shared Library Issues in AWS Lambda

Running FFmpeg inside AWS Lambda often results in shared library errors, such as “error while loading shared libraries,” because the minimal Lambda execution environment lacks the required multimedia codecs and system-level dependencies. This article provides a direct, actionable guide to resolving these dependency issues using static FFmpeg builds, AWS Lambda Layers, or Docker container images.

Understanding the Cause

AWS Lambda runs on lightweight Amazon Linux microVMs. When you deploy a standard FFmpeg binary, it dynamically searches for shared libraries (.so files) in the system. Because Lambda’s environment lacks these libraries, the execution fails. To fix this, you must supply FFmpeg in a format that does not rely on the host system’s dynamic libraries.

Solution 1: Use a Statically Linked FFmpeg Binary

The easiest way to resolve dependency issues is to use a statically compiled version of FFmpeg. Static binaries contain all necessary libraries bundled directly inside the single executable file.

  1. Download a Linux Static Build: Download a trusted, pre-compiled static FFmpeg binary designed for the target architecture of your Lambda function (typically x86_64 or arm64/Graviton2).

  2. Include Binary in Deployment Package: Place the ffmpeg and ffprobe executables in a bin/ directory within your project folder.

  3. Set Executable Permissions: Ensure the binaries have the correct execution permissions before zipping your deployment package. You can set this in your terminal using:

    chmod 755 bin/ffmpeg
  4. Reference the Path in Code: Point your application code to the relative path of the bundled binary (e.g., ./bin/ffmpeg).

Solution 2: Use AWS Lambda Layers

If you want to keep your deployment package small, or if you share FFmpeg across multiple Lambda functions, package the static binary into an AWS Lambda Layer.

  1. Create the Directory Structure: On your local machine, create a directory named bin.

  2. Add FFmpeg: Place your statically compiled ffmpeg executable inside that bin directory.

  3. Zip the Layer: Zip the parent directory. The structure of the zip file must be:

    ffmpeg-layer.zip
    └── bin/
        └── ffmpeg
  4. Upload the Layer: Create a new Lambda Layer in the AWS Console or via AWS CLI using this zip file.

  5. Attach the Layer: Add the layer to your Lambda function. AWS Lambda automatically extracts layer contents into the /opt directory at runtime. The executable will be located at /opt/bin/ffmpeg.

  6. Update the Environment PATH: Add /opt/bin to your Lambda function’s PATH environment variable, or reference /opt/bin/ffmpeg directly in your code.

Solution 3: Deploy Lambda as a Container Image (Docker)

For complex workflows requiring additional system libraries alongside FFmpeg, package your Lambda function as a Docker container. This gives you complete control over the operating system dependencies.

  1. Write a Dockerfile: Use an official AWS Lambda base image and install FFmpeg during the build process.

    FROM public.ecr.aws/lambda/nodejs:18
    
    # Install tar and xz to extract the static build
    RUN yum install -y tar xz
    
    # Download and extract static FFmpeg binary
    ADD https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz /tmp/
    RUN cd /tmp && \
        tar -xf ffmpeg-release-amd64-static.tar.xz && \
        mv ffmpeg-*-amd64-static/ffmpeg /usr/local/bin/ && \
        mv ffmpeg-*-amd64-static/ffprobe /usr/local/bin/ && \
        rm -rf /tmp/*
    
    # Copy function code
    COPY index.js package.json ${LAMBDA_TASK_ROOT}/
    
    CMD [ "index.handler" ]
  2. Build and Push: Build the Docker image, push it to Amazon Elastic Container Registry (ECR), and configure your Lambda function to deploy from the container image. This eliminates all shared library discrepancies by ensuring the runtime environment matches your build environment exactly.