Lambda limitations
Where Overcast's Lambda diverges from AWS, in one table, with the page carrying the detail behind each row: concurrency, execution environments, event delivery, logging and runtimes.
Every divergence from AWS behind Lambda, and the page that carries the detail.
Divergences
| Area | Divergence | Detail |
|---|---|---|
| Async invocation | Retries, destinations and DLQ all work; only the exhausted-concurrency retry-to-queue case differs from AWS | Event delivery |
| Partial batch responses | ReportBatchItemFailures is honoured; an unreadable response fails the whole batch | Event delivery |
| Concurrency quotas | Account-wide quotas and requests-per-second limits are not emulated; only reserved concurrency is enforced | Concurrency |
| Cold-start latency | Not simulated | Execution environments |
| Runtime environment validation | Minimal | Runtimes |
| Extension telemetry (Logs API / Telemetry API) | HTTP destinations only | Logging |
| SnapStart | Not emulated — no restore records; platform.runtimeDone reports only responseLatency | Logging |
LoggingConfig: {} (explicitly empty) | UpdateFunctionConfiguration returns 501 | Logging |
TracingConfig / EphemeralStorage / KMSKeyArn | Stored and returned, never enforced | Below |
| Resource policies | Evaluated for service-originated invokes only, and only under a knob; PutResourcePolicy always refuses a public policy | Below |
| Update status | Every update but an image UpdateFunctionCode answers Successful rather than InProgress | Below |
Unqualified DeleteFunction | Removes the function record; versions, aliases and version counters are left behind | Below |
| Tagging | Functions and event source mappings only; other taggable resources return 501 | Below |
Pinned Code.S3ObjectVersion | Excluded from the reactive S3 code sync | Below |
| Reactive S3 code sync | Only moves a function onto bytes it is not already running | Below |
| VPC placement | Not restricted on a native Windows or macOS host | Below |
Recorded but not honoured
TracingConfig, EphemeralStorage and KMSKeyArn are validated against AWS’s
own constraints, stored, and returned by GetFunction,
GetFunctionConfiguration, CreateFunction and UpdateFunctionConfiguration, so
a template or SDK client reads back exactly what it set. None of them changes what
the function does.
| Setting | What it does not do |
|---|---|
TracingConfig | No segment is recorded and no trace exists, whichever Mode is set; Active and PassThrough behave identically |
EphemeralStorage | The size is not enforced — a function configured with 512 MB of /tmp gets whatever the Docker host gives it, normally far more |
KMSKeyArn | An association only; environment variables are stored in plaintext, as all Overcast state is |
Update status
AWS answers every update LastUpdateStatus: InProgress and settles a moment
later. Overcast answers Successful: a zip deployment and every
UpdateFunctionConfiguration are durably applied before the call returns, so
aws lambda wait function-updated returns on its first poll. The one update
that really is asynchronous — UpdateFunctionCode
pointing a PackageType=Image function at a new image — answers InProgress and
settles to Successful, or Failed with
ImageAccessDenied/InvalidImage/InternalError, when the pull does.
Resource policies
AddPermission and PutResourcePolicy always store and validate what they are
given. Whether a statement then decides anything is a switch:
OVERCAST_ENFORCE_LAMBDA_RESOURCE_POLICY, off by default.
Turned on, it gates the invocations Overcast originates on another service’s
behalf — S3 bucket notifications, SNS subscription deliveries, API Gateway
integrations and EventBridge rule targets — against the target’s policy, and
each caller fails the way AWS does: S3 refuses the notification configuration
with InvalidArgument, SNS dead-letters the delivery, API Gateway answers 500,
and EventBridge records a failed invocation. A direct Invoke is never gated in
either setting: Overcast accepts credentials without validating them, so there
is no caller identity to authorise.
Three things the evaluation does not do. A condition key it cannot evaluate —
anything but aws:SourceArn and aws:SourceAccount — refuses the statement
rather than ignoring the condition. A policy is read at the qualifier being
invoked, so a Resource ending :* written against the unqualified function
does not reach its own aliases. And EventBridge Scheduler is not gated at all,
because AWS grants it through an execution role instead.
The reactive S3 code sync
An unpinned function is moved onto new bytes when a new object lands at its
S3Bucket/S3Key. Two limits apply:
- A function whose code names a
Code.S3ObjectVersionis pinned to that version and excluded from the sync, which matches AWS. UseUpdateFunctionCodeto move it. - The sync only moves a function onto bytes it is not already running. A
PutObjectre-uploading an unchanged asset, or one landing just before aCreateFunctionreads the same key, is not a new deployment:RevisionIdandLastModifiedstay put and the warm environment survives.
Deleting a version, and where tags live
DeleteFunction means two different things depending on whether you pass a
qualifier — either as ?Qualifier= or inside the function name (my-function:2):
| Request | Effect |
|---|---|
DELETE /functions/my-function | Deletes the function, its package and its resource policies |
DELETE /functions/my-function?Qualifier=2 | Deletes only published version 2, its qualified policy and its provisioned concurrency |
?Qualifier=$LATEST | 400 InvalidParameterValueException — $LATEST only goes with the function |
| Qualifier naming a version an alias points at | 409 ResourceConflictException naming the aliases |
| Qualifier naming an alias | 409 ResourceConflictException — DeleteFunction never deletes an alias |
| Qualifier naming neither | 404 ResourceNotFoundException |
A qualified delete never touches $LATEST, the function record, other versions,
aliases or unqualified policies, and it does not rewind the version counter — AWS
never reuses a version number.
Tags attach to the unqualified function ARN, never to a version or alias, so
TagResource, UntagResource and ListTags reject a qualified ARN with
InvalidParameterValueException. They take an ARN, not a bare function name.
Event source mappings are taggable through the same three operations, and
CreateEventSourceMapping accepts a Tags map, as CloudFormation sends on
every deploy carrying stack tags. Their tags are stored separately and
never appear in EventSourceMappingConfiguration, so ListTags is the only way
to read them back. Code signing configurations, capacity providers and network
connectors return 501 from the tag operations.
VPC placement — VpcConfig
A function with a VpcConfig naming subnets is placed on that VPC’s network and
nothing else. It can reach what is in the VPC with it and cannot reach a
container outside it, matching AWS, where placement subtracts rather than adds.
Important
On a native Windows or macOS host the restriction is not applied. It needs
Overcast’s DNS resolver, and that needs an /etc/resolv.conf those hosts do
not have. There the function joins its VPC network and the shared data
plane and reaches everything on both, so a test of your VPC wiring passes
whether or not the wiring is correct. Run Overcast in a container to get the
restriction. See Networking § The Docker networks Overcast uses.
Overcast’s own API endpoint is the exception and stays reachable from every
function regardless of placement. AWS_ENDPOINT_URL and the Lambda Runtime API
ride a separate control plane, so calling S3 or DynamoDB from inside a VPC works
here without the NAT gateway or VPC endpoint AWS would need.
A database in a VPC with the function outside it never worked on AWS either.
Put the function in the VPC, or set PubliclyAccessible on the instance; the
refused connection is named rather than left to hang.
Related
- Lambda — quick start and what works
- Lambda concurrency — the instance and memory limits
- Lambda execution environments — what retires a warm container
- Lambda event delivery and retries — retries, destinations, batch failures
- Lambda logging — the JSON record vocabulary and its levels
- Lambda runtimes — identifiers, deprecation dates, images
- Lambda troubleshooting — throttles, layer errors, extension endpoints
- Lambda operations — per-operation status
- Lambda, ECS and VPCs — what VPC membership restricts