Lambda layer conversion failed.

Short answer

The layer archive uploaded successfully and Lambda could not turn it into a usable layer. The upload is not the validation — the archive is inspected afterwards, which is why this arrives as a separate failure rather than at publish time.

What it means

Publishing a layer is two steps that look like one. Lambda takes the bytes, and then it processes them into something it can mount at /opt on a function's execution environment. This error belongs to the second step: the transfer worked and the conversion did not.

That separation explains why the failure feels late. Nothing about the upload complains — the size was acceptable, the API call was well formed — and the rejection arrives afterwards, describing the archive rather than the request.

Most causes are the ordinary ways an archive can be unusable, and they are the same ones that make a function package fail to unzip: not actually a zip, truncated in transit, or built with a compression method Lambda does not read. Checking with file and unzip -t in the build catches all three before anything is uploaded.

The layer-specific cause is structure. A layer's contents are extracted to /opt, and each runtime adds only particular subdirectories of that to its search path — /opt/python for Python, /opt/nodejs/node_modules for Node, /opt/java/lib for Java. A layer built by zipping the packages directly, rather than a directory containing them, has nothing where the runtime looks. When that merely produces a wrong layout it publishes fine and contributes nothing; when it produces something Lambda cannot place at all, you get this.

Worth remembering alongside it: a layer counts toward the same 250 MiB unzipped limit as the function it attaches to. Layers are useful for sharing a dependency set across functions and for keeping deployment packages small, and they do not raise that ceiling — so a layer created specifically to hold something large is the most likely thing to run into it.

Where you'll see it

Deployment output

Not in CloudWatch
$ aws lambda publish-layer-version \
--layer-name shared-deps \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.12
An error occurred (InvalidParameterValueException) when calling the PublishLayerVersion
operation: Lambda layer conversion failed. For advice on resolving this issue, see the
Troubleshoot deployment issues in Lambda page.

This failure happens before the function runs, so nothing about it reaches CloudWatch Logs — there is no invocation, and no log group entry to find. Once the deployment succeeds and the function starts running, the rest of this index covers what you will see there.

Causes, most likely first

1

The archive is not a readable zip

How to confirm

Run file and unzip -t on it. A tarball, a truncated upload, or a zip using an unusual compression method all upload without complaint and cannot be processed — the same family of causes as a function package that will not unzip.

2

The layer exceeds the size limit

How to confirm

Measure the extracted size. A layer counts toward the same 250 MiB unzipped ceiling as the function package it attaches to, and a layer built to hold a large dependency is exactly the thing likely to cross it.

3

The internal directory structure is wrong for the runtime

How to confirm

Check for the runtime's expected top-level directory. Python needs python/, Node needs nodejs/node_modules/, and Java needs java/lib/. A layer zipped from the wrong root has contents Lambda cannot place.

4

The archive contains symlinks pointing outside it

How to confirm

List the archive for links. Dependency installers occasionally create symlinks — .bin entries in node_modules are the common case — and links that resolve outside the archive cannot be extracted.

Fixes

Fix 1

Validate the archive before publishing

The same three commands that catch a bad function package catch a bad layer, and running them in the build is cheaper than a failed publish.

bashfile layer.zip
unzip -t layer.zip > /dev/null && echo "archive is valid"
unzip -l layer.zip | head -5
Fix 2

Build the layer with the directory structure the runtime expects

A layer extracts to /opt, and each runtime only adds specific subdirectories to its search path. Getting the top-level directory wrong produces a layer that publishes and contributes nothing — or, when it cannot be processed at all, this error.

bash# Python: contents must sit under python/
mkdir -p python
pip install -r requirements.txt --target python/
zip -qr layer.zip python/

# Node: under nodejs/node_modules/
mkdir -p nodejs
cp package.json nodejs/ && (cd nodejs && npm ci --omit=dev)
zip -qr layer.zip nodejs/
Fix 3

Publish large layers through S3

Direct upload is where truncation happens. S3 verifies the object on write, and publishing from a key removes a whole class of partial-transfer failure.

bashaws s3 cp layer.zip s3://my-artifacts/layers/shared-deps-42.zip
aws lambda publish-layer-version \
  --layer-name shared-deps \
  --content S3Bucket=my-artifacts,S3Key=layers/shared-deps-42.zip \
  --compatible-runtimes python3.12
Fix 4

Strip symlinks the archive cannot carry

Where a dependency installer has produced links, dereferencing or excluding them avoids an archive that cannot be extracted intact.

bashzip -qr layer.zip python/ -x '*/.bin/*'

Also seen as

The same underlying failure, worded differently by a different runtime, SDK version, or logging layer. All of these land here — there is no separate page for each phrasing.

Lambda layer conversion failed. For advice on resolving this issuelambda layer conversion failedlambda layer failed to publishlambda layer invalid archive

Errors that show up alongside this one, or that people mistake for it.

References

This one happens before there are any logs.

LogStitch reads CloudWatch, and a deployment that fails never writes to it — so this is not an error it can find for you. Once the function deploys and starts running, the free web stitcher groups its invocations in your browser, and the Mac app does the same across every function in your account.