CloudFront Distribution not serving S3 Bucket pages unless /index.html included in URL


I have a Gatsby site that I upload to an S3 bucket. The S3 bucket has all public access blocked and its domain ( is the origin of a CloudFront distribution. I set it up so that the CDN is using an OAI to access content in the S3 bucket. When I originally uploaded this content, it worked fine: I could go to <my-cdn> and it would serve up the s3::my-bucket/index.html file.

I'm not sure if this caused my issue, but after adding a step in my CI/CD process (Azure Pipelines) to invalidate the CDN cache after it's uploaded my Gatsby build to the S3 Bucket, now I can't access <my-cdn> via a browser.

  • Now I have to include /index.html in the URL (like .../test-page/index.html) which serves the static document successfully and changes the url to .../test-page/.
  • If I try to use the path with a trailing/ (like .../test-page/) before I've gone to .../test-page/index.html, I get access denied. But once I go to .../test-page/index.html and it loads the page and changes the url to .../test-page/index.html then I can go directly to .../test-page/ and it loads fine. .../test-page still fails however.

How do I get my CDN/S3 configuration to serve the .../path/index.html file whether the url is .../path or .../path/? Do I need to set up specific routing rules? That seems excessive to force a bunch of redirects (.../path > .../path/index.html > .../path/)...

It worked when I originally set it up, so could this be an issue with my Gatsby build instead? When I run gatsby develop locally, I'm able to access it by going to .../page, so I don't think the build would be the issue...


I ended up solving it with a Lambda Edge function, but I am still curious if that is a required step with the CDN - S3 set up with these types of Static Site configurations

1 Answer

Did you try to set a default root object on CloudFront Distribution level?

It should do exactly what you want.

The object (file name) to return when a viewer requests the root URL (/) instead of a specific object.

Additionally, if you will really need a Function to fix this problem, you should consider using CloudFront Function instead of Lambda@Edge. It's cheaper and faster :) more you can find here.

profile picture
answered 2 years ago
  • yup, I have my default root object set to index.html which is why I was a bit confused why it suddenly stopped working.

    I'll check out the CloudFront Function instead, thanks!

  • I think the default root object works only for the root domain <my-cdn> or <my-cdn>, that's why if you are trying <my-cdn> it is not working.

    There are two things:

    • If your index.html on S3 is in the folder like test-page/index.html then you need to have the same structure in the default root object -> test-page/index.html
    • If you want to serve index.html under <my-cdn> then I believe that you need to use Function.

    You can find an example of how the default root object works here.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions