Fix FFmpeg Shared Library Errors in AWS Lambda

Running FFmpeg inside an AWS Lambda environment frequently triggers errors like error while loading shared libraries: libXYZ.so: cannot open shared object file due to missing dynamic dependencies in the underlying Amazon Linux runtime. This article provides a straightforward guide to diagnosing and resolving these dependency conflicts using three proven approaches: deploying statically compiled binaries, building compatible shared libraries using Lambda layers, and packaging your application inside a container image.

Why Shared Library Errors Occur in Lambda

AWS Lambda functions run on minimal Amazon Linux environments (Amazon Linux 2 or Amazon Linux 2023). If you upload an FFmpeg binary compiled on a standard Linux distribution like Ubuntu or Debian, it will attempt to dynamically link to specific versions of shared libraries (glibc, libx264, libssl, etc.) at runtime. When Lambda cannot find these .so files in its default library paths (/lib64, /usr/lib64), execution halts immediately.


The simplest and most reliable way to avoid shared library dependencies is to use a completely static FFmpeg build. A static binary packages all required libraries directly into the single executable, eliminating external .so dependencies.

  1. Download a pre-compiled static release for Linux x86_64 or ARM64 (matching your Lambda function's architecture) from a trusted source such as John Van Sickle's static builds:

    wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
    tar -xf ffmpeg-release-amd64-static.tar.xz
  2. Extract the ffmpeg and ffprobe binaries.

  3. Place these binaries in your project root or package them into a Lambda Layer under a bin/ directory:

    ffmpeg-layer.zip
    └── bin/
        ├── ffmpeg
        └── ffprobe
  4. Upload the zip as a Lambda Layer. When attached to your function, files located in /opt/bin can be executed directly or called by updating your runtime's PATH environment variable:

    PATH=/opt/bin:$PATH

Solution 2: Build Shared Libraries in an Amazon Linux Environment

If your project requires customized build flags or codecs that necessitate dynamic linking, you must compile FFmpeg inside the exact environment that Lambda uses.

1. Compile Using the AWS Lambda Docker Image

Run a container matching your Lambda runtime (e.g., Amazon Linux 2023) to build the libraries:

docker run -it --entrypoint /bin/bash public.ecr.aws/lambda/provided:al2023

Inside the container, install the build tools and dependencies:

dnf groupinstall "Development Tools" -y
dnf install nasm yasm -y

Compile FFmpeg along with your required external libraries from source.

2. Locate and Bundle the Shared Libraries

Run ldd against your compiled FFmpeg binary to list all required dynamic libraries:

ldd ffmpeg

Identify any libraries not natively provided by the Lambda runtime. Copy the ffmpeg executable and all required .so files into the standard Lambda layer directory layout:

ffmpeg-layer/
├── bin/
│   └── ffmpeg
└── lib/
    ├── libavcodec.so
    ├── libavformat.so
    └── libavutil.so

3. Configure the Runtime Paths

Zip the directory and attach it to your Lambda function. AWS Lambda automatically adds /opt/lib to LD_LIBRARY_PATH and /opt/bin can be targeted explicitly in your execution command:

const { execSync } = require('child_process');
execSync('/opt/bin/ffmpeg -i input.mp4 output.avi');

Solution 3: Package as a Docker Container Image

If managing dynamic layers exceeds file size limits or introduces version mismatch headaches, deploy your Lambda function as an OCI-compliant container image.

Create a Dockerfile based on the official AWS Lambda base image:

FROM public.ecr.aws/lambda/nodejs:20

# Install FFmpeg and runtime dependencies
RUN dnf install -y ffmpeg

# Copy function code
COPY app.js ${LAMBDA_TASK_ROOT}

CMD [ "app.handler" ]

Building inside the container guarantees that all dynamically linked libraries are correctly configured and present in standard system paths when the Lambda function boots.