Multiple Cloudfront Origins with Behavior Path Redirection
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
CloudFront can route different URL paths to different origins, which makes one distribution capable of serving a whole application stack. The important detail is that cache behavior matching and URI rewriting are separate features, and mixing them up causes many broken configurations.
How Multiple Origins Actually Work
A CloudFront distribution can contain several origins, such as:
- an S3 bucket for static assets
- an Application Load Balancer for an API
- another HTTP origin for legacy content
Each cache behavior selects exactly one origin based on a path pattern. For example:
- '
static/*goes to the S3 origin' - '
api/*goes to the ALB origin' - '
*falls back to the default origin'
That routing decision happens before the request reaches the origin. CloudFront evaluates the incoming request path against behavior precedence and picks the first matching behavior.
Routing vs Path Rewrite
This is the part that trips people up: changing the request URI with a CloudFront Function or Lambda@Edge does not change which cache behavior matched the request. AWS documents this explicitly.
That means a request for /api/users can match the api/* behavior and be sent to the API origin, but if you rewrite the URI to /users in a viewer-request function, the origin is still the one chosen by the api/* behavior. The rewrite changes the path sent onward, not the behavior selection that already happened.
That distinction is useful. You can route by one prefix and send a cleaned-up path to the origin.
Common Pattern
Suppose you want:
- '
/assets/*served from S3' - '
/api/*served from an application origin' - the
/api/prefix removed before the origin receives the request
Behavior setup:
- behavior
assets/*-> S3 origin - behavior
api/*-> app origin - default
*-> website origin
Then attach a CloudFront Function to the api/* behavior:
Now /api/orders is routed by the api/* behavior to the app origin, but the app receives /orders.
When Origin Path Is Enough
Sometimes you do not need a function at all. If every request for an origin should include a fixed prefix, use the CloudFront Origin Path setting instead.
Example:
- viewer requests
static/logo.png - behavior routes to S3 origin
- origin path is
/public - CloudFront fetches
/public/static/logo.pngfrom the origin
This is simpler than a function, but it only works when the added prefix is static. It does not remove arbitrary incoming prefixes or apply conditional logic.
Testing the Setup
You can validate the behavior mapping with predictable test paths:
Then inspect:
- response headers
- origin logs
- CloudFront function logs
If /api/health still hits the default origin, the issue is usually path-pattern precedence, not the rewrite code.
Common Pitfalls
The biggest mistake is expecting a URI rewrite to re-evaluate behaviors. It does not. If you need a different origin, fix the behavior path patterns first.
Another common issue is overlapping patterns with the wrong precedence. A broad rule can accidentally capture traffic intended for a more specific origin.
Developers also confuse redirects with rewrites. A redirect returns a response to the browser and changes the visible URL. A rewrite changes the request CloudFront sends onward without changing what the browser shows.
Finally, do not overuse edge logic when Origin Path or a cleaner origin application route would solve the same problem with less moving parts.
Summary
- CloudFront behaviors choose the origin based on path-pattern matching.
- URI rewrites and behavior selection are separate steps.
- Rewriting the URI does not change the behavior or origin already selected.
- Use CloudFront Functions or Lambda@Edge when you need dynamic path manipulation.
- Use
Origin Pathwhen a fixed prefix is enough and you want a simpler setup.

