- Newest
- Most votes
- Most comments
Hello.
You might want to check the CloudFront standard logs.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html
By the way, would it be possible for you to share the CloudFormation template or similar resources used to reproduce the issue?
Based on the behavior you're describing, this appears to be working as designed, though I understand it's counterintuitive. Here's what's happening:
When CloudFront receives a 404 from your primary S3 origin, it caches that 404 response at the edge according to your error caching settings (ErrorCachingMinTTL: 60 seconds). Even though CloudFront then fails over to your Lambda secondary origin and receives a successful 200 response, both responses are cached separately - the 404 from S3 and the 200 from Lambda.
However, here's the critical part: CloudFront's request routing logic checks the primary origin first on subsequent requests. Since the 404 from S3 is cached (for 60 seconds), CloudFront will continue to serve from that cached error state and fail over to Lambda again, rather than serving the cached 200 response from Lambda. This explains why your second request still shows a Miss - CloudFront is checking S3 first, finding the cached 404, then failing over.
Once your Lambda function writes the object to S3 and the error cache expires (after 60 seconds), subsequent requests will find the object in S3 and cache that response normally. This is why your third request becomes a Hit - by then, the 404 error cache has likely expired, CloudFront finds the object in S3, and caches it.
The key issue is the interaction between error caching and origin group failover behavior. When you configure custom error responses with ErrorCachingMinTTL, CloudFront caches the error status codes (404, 403) for that duration. During this caching period, CloudFront's behavior with origin groups means it will continue to see the cached error from the primary origin and trigger failover, rather than serving a previously cached successful response from the secondary origin.
To improve this behavior, you could:
-
Reduce ErrorCachingMinTTL to a very low value (even 0-1 seconds) for 404 errors, so the cached error expires almost immediately after Lambda writes the object to S3.
-
Remove the custom error response configuration for 404 if you don't need custom error pages, allowing CloudFront to use its default error caching behavior.
-
Consider a different architecture where Lambda writes to S3 first, then returns a redirect to the S3 URL, though this adds latency.
The behavior you're seeing with Lambda Function URLs as a secondary origin is consistent with how CloudFront handles any custom origin in an origin group - it's not specific to Lambda Function URLs. The documentation stating that "response behavior is the same as for a CloudFront origin that's not in an origin group" is accurate for the caching of the successful response itself, but doesn't account for how the cached error from the primary origin affects subsequent request routing.
This is expected behavior given your configuration, not a bug or undocumented limitation, though it does create the caching inefficiency you've observed.
Sources
How CloudFront processes HTTP 4xx and 5xx status codes from your origin - Amazon CloudFront
answered 2 months ago
This makes no sense. CF shouldn't cache the 404 of the primary origin when there's failover and the secondary succeeds.
Tried disabling
CustomErrorResponses. Same issue still occurs.
Relevant content
asked 2 years ago
asked 6 years ago
asked 2 years ago

Here are the logs: https://pastebin.com/CHHU7tVR
Will try to recreate this with CloudFormation and share the template.