- Newest
- Most votes
- Most comments
The behavior you are seeing is expected: with "All Viewers Except Host", because CloudFront always overrides the Host header with the origin's domain name to ensure the request reaches the correct endpoint (especially critical for S3).
The 502 error when using originOverrides.hostHeader suggests a conflict between the Origin Request Policy and the Function runtime's attempt to modify a protected header for a specific origin in a group. So, CloudFront Functions currently lacks the "Origin Request" context that Lambda@Edge has (which triggers after the origin is selected). As far as I know, using a custom header is the only way to satisfy S3's requirement while providing the necessary routing data to your ALB without hitting the 502 validation error in createRequestOriginGroup.
Since you want to stay within CloudFront Functions and avoid a 502, you should shift the routing logic from the Host header to a custom header:
- Keep Policy: Maintain "All Viewers Except Host" so S3 continues to work.
- Pass CloudFront Domain: In your Origin Request Policy, ensure the original Host (your CloudFront domain) is forwarded as a custom header, e.g.,
X-Forwarded-Host. - Update Backend: Update your ALB/EC2 application logic to use the value of
X-Forwarded-Hostfor routing instead of the Host header.
Based on the error message "The CloudFront function returned an invalid value for origin rewrite," this indicates that CloudFront Functions is rejecting the way the host header is being set through the originOverrides parameter.
The issue you're encountering appears to be related to how CloudFront Functions validates header rewrites. When using CloudFront Functions, there are restrictions on which headers can be modified and how they can be set. The error suggests that the originOverrides.hostHeader approach may be triggering a validation error within the CloudFront Functions runtime.
For your specific use case, here's a recommended workaround:
Instead of using originOverrides.hostHeader in createRequestOriginGroup(), you can manually set the host header in your CloudFront Function based on which origin will be used. Since you need different host header values for S3 versus ALB, you can conditionally set the host header in the request object before returning it:
import cf from 'cloudfront'; async function handler(event) { const request = event.request; cf.createRequestOriginGroup({ "originIds": [ { "originId": "my-s3-origin" }, { "originId": "my-alb-origin" } ], "failoverCriteria": { "statusCodes": [403, 404, 500, 502, 503] } }); // Manually set the host header for the ALB failover case // This will be used when failover occurs request.headers['host'] = { value: 'myDomain.cloudfront.net' }; return request; }
However, this approach has a limitation: the same host header will be sent to both origins. To work around this while keeping S3 functional, you may need to reconsider your architecture:
- Use separate cache behaviors with different origin request policies for different URL patterns
- Configure your S3 bucket to accept the CloudFront domain as a valid host header
- Use Lambda@Edge instead of CloudFront Functions, which provides more flexibility in origin selection and header manipulation
- Consider using two separate distributions or cache behaviors to handle S3 and ALB origins independently
The originOverrides feature in createRequestOriginGroup() may have limitations or validation rules that aren't fully documented, and your experience suggests it may not be working as expected in the current runtime version.
Sources
Troubleshoot CloudFront function URI rewrite issues | AWS re:Post
HTTP 502 status code (Bad Gateway) - Amazon CloudFront
Thank you for taking the time to respond!
However, after reviewing your suggestions, I don't think they address my core issue. Let me clarify my specific constraints and what I'm looking for:
My constraints:
I want to solve this within CloudFront Functions (not Lambda@Edge) I'm using an Origin Group where the primary origin is S3 and the failover is ALB With Origin Request Policy set to "All Viewers Except Host", S3 works correctly — but ALB (and the backend behind it) receives its own domain (my-alb.us-east-2.elb.amazonaws.com) as the Host header instead of the CloudFront domain My backend requires the original CloudFront domain as the Host header for routing logic My core question:
Why does the CloudFront Host header disappear when a request is forwarded through ALB to the backend? Is this a known behavior with Origin Groups + "All Viewers Except Host" policy?
And more importantly: is there any supported way within CloudFront Functions to set a per-origin Host header override — specifically for the ALB origin only — so that:
S3 continues to receive its own bucket domain as Host (so it doesn't return 403), and ALB and the services behind it receive the CloudFront domain (myDomain.cloudfront.net) as Host? Your suggestion of setting request.headers['host'] manually would apply the same host to both S3 and ALB, which breaks S3. That's exactly the problem originOverrides.hostHeader in createRequestOriginGroup() was intended to solve — but it currently causes a 502 regard
Relevant content
- asked 2 years ago

If my answer was helpful, I would appreciate it if you could mark it as the accepted answer.