InvalidParameterValueException: Lambda was unable to configure your environment variables because the environment variables you have provided exceeded the 4KB limit.

Short answer

All of the function's environment variables together exceed 4 KB. The limit is on the combined size of every key and value, not on any single one and not on the count — and it is a hard service limit that no quota increase will raise.

What it means

Lambda allows 4 KB for a function's entire environment — every key and every value, added together. There is no cap on how many variables you may have, and no cap on any individual one; the only thing measured is the total, and 4,096 bytes is less room than it sounds once real values are in it.

The limit is reached in two characteristically different ways. The first is a single large value: a PEM certificate, a private key, a service-account JSON document. Any one of those can take a quarter of the budget or more, and they end up in environment variables because it is the path of least resistance for getting a secret into a function. The second is accumulation. No individual variable is unreasonable, but a service that has collected endpoints, feature flags, table names, queue URLs and tuning parameters over a couple of years crosses the line on a change that adds almost nothing — which is why this so often appears alongside a trivial diff.

ARNs deserve a specific mention because they are so easy to overlook. A full ARN runs well past a hundred characters, and a function wired to a dozen resources is spending over a kilobyte on identifiers before any actual configuration. Passing resource names and constructing the ARNs in code, using the region and account already present in the runtime environment, recovers a surprising amount of room.

There is a security argument that points the same way as the size one. Environment variables are readable by anyone who can call GetFunctionConfiguration, and they appear in the console. If a certificate or an API key is what pushed you over 4 KB, the limit has surfaced a problem worth fixing rather than working around — Secrets Manager or Parameter Store solves both at once, and fetching at module scope means one call per execution environment rather than one per invocation.

None of this reaches CloudWatch Logs. The configuration is rejected, the function keeps its previous environment, and it carries on running exactly as before — so the only evidence is in the deployment's own output.

Where you'll see it

Deployment output

Not in CloudWatch
$ aws lambda update-function-configuration \
--function-name orders-fn \
--environment file://env.json
An error occurred (InvalidParameterValueException) when calling the
UpdateFunctionConfiguration operation: Lambda was unable to configure your environment
variables because the environment variables you have provided exceeded the 4KB limit.

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

A certificate, key or JSON blob is being passed as a variable

How to confirm

Look for the longest values. A PEM certificate, a private key, a service-account JSON document or a base64 bundle will each consume a large fraction of the budget on its own, and these are the values most often moved into environment variables for convenience.

2

Configuration accumulated one variable at a time

How to confirm

Sum the sizes rather than counting the entries. No single addition looks unreasonable, and a function that has collected forty feature flags, endpoints and tuning values over two years crosses the limit with a change that adds twenty bytes.

3

A deployment tool is injecting variables you did not write

How to confirm

Compare the variables in your template against what the function actually has. Framework plugins, observability layers and CI systems all add their own, and those count toward the same 4 KB.

4

Long ARNs are being passed for many resources

How to confirm

Measure the ARNs. A full ARN runs to over a hundred characters, so a function wired to a dozen queues, tables and topics is spending well over a kilobyte on identifiers alone.

Fixes

Fix 1

Measure what is actually consuming the budget

Before removing anything, find where the bytes are. It is almost always one or two values rather than the many small ones people start deleting.

bashaws lambda get-function-configuration --function-name orders-fn \
  --query 'Environment.Variables' --output json |
python3 -c "
import json,sys
env = json.load(sys.stdin)
rows = sorted(((len(k) + len(v), k) for k, v in env.items()), reverse=True)
print(f'total {sum(n for n, _ in rows)} bytes across {len(rows)} variables\n')
for n, k in rows[:15]:
    print(f'{n:>6}  {k}')
"
Fix 2

Move secrets and large values out of the environment

Certificates, keys and credentials should not be environment variables anyway — they are visible to anyone with GetFunctionConfiguration. Storing them in Secrets Manager or Parameter Store solves the size problem and the exposure problem together, and the value is fetched once per execution environment rather than per invocation.

jsimport { SecretsManagerClient, GetSecretValueCommand }
  from "@aws-sdk/client-secrets-manager";

const client = new SecretsManagerClient({});

// Module scope: one fetch per execution environment, not per invocation.
let cached;
async function signingKey() {
  cached ??= (await client.send(
    new GetSecretValueCommand({ SecretId: process.env.SIGNING_KEY_ID })
  )).SecretString;
  return cached;
}
Fix 3

Pass one config pointer instead of many values

Where a function needs a lot of configuration, a single parameter naming a config object is far more compact than the configuration itself — and it lets the config change without a deployment.

yamlEnvironment:
  Variables:
    # Instead of forty individual settings:
    CONFIG_PARAM: /orders/prod/config
    AWS_REGION_OVERRIDE: !Ref AWS::Region
Fix 4

Derive what you can rather than passing it

Several values are already available to the function without being configured. The region and the function name are in the runtime environment, and an ARN can often be constructed from a resource name plus the region and account rather than passed whole.

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.

the environment variables you have provided exceeded the 4KB limitlambda environment variables 4kb limitlambda too many environment variableslambda env var size limit

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.