“The specified key does not exist” for Static Websites Hosted on S3 behind CloudFront

If you’ve deployed a static website on an S3 bucket behind a CloudFront distribution & encountered the following error when you navigate the site, this post is for you.

Weirdly, this will work if you hit the same object’s S3 URL directly, but not if you go via CloudFront. So what’s going on here? Let’s find out.

S3 buckets have 2 endpoints — REST & website. Each has different capabilities. The website endpoint resolves to the index.html document but REST doesn’t. When you configure a CloudFront distribution in front of an S3 bucket that’s hosting a static website, do NOT set the distribution’s origin as an S3 origin, set it as a custom origin.

When you create a CloudFront distribution, you’ll see a drop-down list of all resources in your account that can be used as origins for the distribution:

For S3 buckets with static websites, do NOT select their S3 bucket from the drop-down. Instead, manually copy-paste their website endpoint from the S3 console without the preceding “http:”:

If you select the S3 origin, CloudFront uses the REST endpoint for the bucket, which allows authentication & private content, which the web site endpoint doesn’t.

On the Create Distribution page, in the Origin Settings section, for Origin Domain Name, enter the Amazon S3 website endpoint for your bucket, for example, example.com.s3-website.us-west-1.amazonaws.com.

Speeding up your website with Amazon CloudFront

Notice how the error at the beginning of this post is XML. That’s because CloudFront has been configured with the S3 origin, not the custom origin. When using a custom origin, errors are in HTML.

Also see Key differences between a website endpoint and a REST API endpoint.

Here’s a complete step-by-step guide — How do I use CloudFront to serve a static website hosted on Amazon S3?