Serve index.html in subfolders with S3/Cloudfront?

I’m having trouble serving HTML files stored in an S3 bucket via Cloudfront. The bucket is called www.foo.site and it has a landing page, an about page, and several pages in different folders (e.g. bar/a/index.html, bar/b/index.html).

When I browse to the landing page URL (www.foo.site) it works, but when I try to navigate to any of the other pages (e.g. /about/index.html or /bar/index.html) I get a 404 error.

I’ve tried setting the origin path and origin domain name in two different ways, but neither has worked:

Try 1:
Domain Name: www.foo.site.s3.amazonaws.com
Origin Path: (blank)

Try 2:
Domain Name: s3-us-west-1.amazonaws.com
Origin Path: www.foo.site

Both tries have had the default document set as index.html.

The strange thing is that all of these pages are browsable directly from S3 (e.g. https://s3-us-west-1.amazonaws.com/www.foo.site/bar/index.html).

I’m not sure what settings I’m missing in Cloudfront or my DNS records that would allow me to serve these HTML files in S3 folders via Cloudfront.

The issue may be due to incorrect cache behavior settings in Cloudfront. In the cache behavior settings, make sure that the “Path Pattern” is set to “*”. This will ensure that all paths are forwarded to the origin.

Additionally, make sure that the S3 bucket policy allows access from the Cloudfront distribution. You can do this by adding a statement to the bucket policy like this:

{
    "Sid": "Allow CloudFront access to S3",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XYZ"
    },
    "Action": [
        "s3:GetObject",
        "s3:ListBucket"
    ],
    "Resource": [
        "arn:aws:s3:::www.foo.site",
        "arn:aws:s3:::www.foo.site/*"
    ]
}

Replace “XYZ” with the ID of your Cloudfront Origin Access Identity.