AWS S3 + CloudFront Subdirectory Hosting: Architecture & Edge Cases
25 Jul 2026, 1:41 pm
Overview
While deploying a static documentation site using AWS S3, CloudFront, and Cloudflare, I came across several edge cases that weren't immediately obvious from the documentation. This post summarizes the issues, their root causes, and the solutions that worked. I'm documenting these as technical notes for future reference, and hopefully they'll be useful to others facing similar problems.
π οΈ Lessons & Gotchas Lesson 1: Local Redirect Caching
Issue
HTTPS configuration and redirect changes worked correctly in Incognito mode, but normal browser sessions continued to show outdated redirects or "Not Secure" warnings.
Root Cause
Modern browsers cache 301 redirects and HSTS policies aggressively. Local cache can continue serving stale routing information even after CloudFront and DNS changes have propagated.
Resolution
Clear the domain's HSTS policy using chrome://net-internals/#hsts. Perform a hard reload (Ctrl + Shift + R / Cmd + Shift + R) with DevTools open. Validate changes using an Incognito window before troubleshooting infrastructure.
Lesson 2: S3 REST Endpoints Do Not Resolve Subdirectory Indexes
Issue
The following requests produced different results:
/iplusflow β 403 Forbidden /iplusflow/ β Object download /iplusflow/index.html β Expected HTML response
Root Cause
CloudFront's Default Root Object applies only to the distribution root (/). When using the S3 REST API endpoint as the origin, S3 treats every request as an object lookup and does not automatically resolve directory requests to index.html.
Resolution
Implement URL rewriting within CloudFront or use the S3 Static Website Endpoint when directory-style routing is required.
Lesson 3: CloudFront Function Execution Stage
Issue
Attaching a CloudFront Function resulted in:
Root Cause
The function was associated with the Viewer Response event while attempting to modify the incoming request. Viewer Response expects a valid HTTP response object, whereas URI rewrites must occur before origin selection.
Resolution
Attach URL rewrite logic to the Viewer Request event and return the modified request object.
Lesson 4: Relative Asset Resolution Depends on Trailing Slashes
Issue
The documentation rendered correctly at:
but loaded without CSS or JavaScript at:
Root Cause
Browsers resolve relative asset paths based on the current URL.
Given:
the browser resolves:
| Request URL | Asset Resolution |
|---|---|
| /iplusflow/ | /iplusflow/styles.css β |
| /iplusflow | /styles.css β |
Without a trailing slash, the browser interprets the final path segment as a file rather than a directory.
Resolution
Redirect directory requests to their trailing-slash equivalent before serving content.
Final CloudFront Function
The following CloudFront Function provides consistent directory routing by: Redirecting directory requests without a trailing slash. Rewriting directory requests to index.html before forwarding thβ¦
https://dev.to/vivekvohra/aws-s3-cloudfront-subdirectory-hosting-architecture-edge-cases-6j1