Redirect to index.html for S3 subfolder
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
If you want a URL such as /docs/ to serve docs/index.html from Amazon S3, the answer depends on which S3 endpoint you are using. The built-in directory-style index behavior works on the S3 static website endpoint, not on the ordinary S3 REST object endpoint.
The Important Distinction: Website Endpoint vs Object Endpoint
S3 has two very different access patterns:
- static website hosting endpoint
- normal object endpoint used for bucket-style object access
The website endpoint understands concepts such as index documents and error documents. The object endpoint does not treat /docs/ as "serve /docs/index.html" in the same website-oriented way.
That distinction is the source of many confusing 403 and 404 behaviors.
Use Static Website Hosting First
If the bucket is hosting a static site, enable static website hosting and set the index document to index.html.
Once that is configured, a request to a path ending in a slash, such as /docs/, can resolve to docs/index.html on the website endpoint.
The critical detail is the trailing slash. A request for /docs/ and a request for /docs are not the same URL.
Folder-Style Example
Suppose your bucket contains:
With static website hosting enabled and index.html configured as the index document, the website endpoint can serve:
- '
/docs/asdocs/index.html' - '
/docs/getting-started.htmldirectly'
That is the normal static-site behavior people expect.
Why It Often Breaks in Practice
The most common reasons this fails are:
- using the S3 REST endpoint instead of the website endpoint
- omitting the trailing slash on the subfolder path
- putting S3 behind CloudFront without adding a rewrite rule
- not actually having
index.htmlin the subfolder
The website endpoint is the part that knows how to treat a path as a website path rather than a raw object lookup.
CloudFront Changes the Story
If you serve the bucket through CloudFront, you often need to decide whether CloudFront should forward directory-style paths exactly or rewrite them.
For example, if the viewer requests /docs, you may want CloudFront logic to rewrite it to /docs/index.html or redirect it to /docs/.
That can be done with:
- a CloudFront Function
- Lambda at Edge
- origin-request or viewer-request rewrite logic
Without that, CloudFront may pass the path through in a way that does not match your folder-style expectations.
Example Rewrite Idea
A simple edge rewrite concept is:
This is not always necessary when you are directly using the S3 website endpoint, but it becomes useful when a CDN or SPA-style routing layer sits in front.
Redirect vs Rewrite
Be clear about what behavior you want:
- redirect means the browser URL changes
- rewrite means the server or edge layer changes the origin object path without changing the visible URL
Many S3 and CloudFront discussions mix those two ideas. Serving index.html for a subfolder often needs a rewrite, not a user-visible redirect.
Common Pitfalls
The biggest mistake is expecting the plain S3 object endpoint to behave like a static website server. Index-document logic lives in the website endpoint behavior.
Another issue is forgetting the trailing slash. /docs and /docs/ are different paths, and website-style index resolution usually assumes the slash form.
Teams also often blame permissions when the real problem is routing. A 403 from S3 static hosting can be a path-resolution symptom, not just an IAM or bucket-policy issue.
Finally, when CloudFront is involved, check whether the CDN is preserving, redirecting, or rewriting the incoming path before it reaches S3.
Summary
- S3 subfolder index behavior works through the static website endpoint, not the plain object endpoint.
- Requests like
/subfolder/can resolve tosubfolder/index.htmlwhen website hosting is configured. - The trailing slash matters.
- CloudFront may require explicit redirect or rewrite logic for folder-style paths.
- Diagnose endpoint type and path handling before assuming the issue is just permissions.
Related reading
- Redirecting EMails with Amazon SES Service
- Reducing memory consumption of mysql on ubuntuaws micro instance
- Referencing env variables from Elastic Beanstalk .ebextensions config files
- Reliability of atomic counters in DynamoDB
- Redux - Where to keep non-serializable Data?
- Redux How to unit test an async action that dispatches another async action
- Remotely debugging my node app that is hosted on AWS
- Remove Kubernetes Readiness Probe

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.