AWS CloudFront access denied to S3 bucket

To assist with your question, I recreated the situation via:

  • Created an Amazon S3 bucket with no Bucket Policy
  • Uploaded public.jpg and make it public via "Make Public"
  • Uploaded private.jpg and kept it private
  • Created an Amazon CloudFront web distribution:
    • Origin Domain Name: Selected my S3 bucket from the list
    • Restrict Bucket Access: Yes
    • Origin Access Identity: Create a New Identity
    • Grant Read Permissions on Bucket: Yes, Update Bucket Policy

I checked the bucket, and CloudFront had added a Bucket Policy similar to yours.

The distribution was marked as In Progress for a while. Once it said Enabled, I accessed the files via the xxx.cloudfront.net URL:

  • xxx.cloudfront.net/public.jpg redirected me to the S3 URL http://bucketname.s3.amazonaws.com/public.jpg. Yes, I could see the file, but it should not use a redirect.
  • xxx.cloudfront.net/private.jpg redirected me also, but I then received Access Denied because it is a private file in S3.

I then did some research and found that this is quite a common occurrence. Some people use a workaround by pointing their CloudFront distribution to the static hosted website URL, but this has the disadvantage that it will not work with the Origin Access Identity and I also suspect it won't receive the 'free S3 traffic to the edge' discount.

So, I waited overnight, tested it this morning and everything is working fine.

Bottom line: Even if it says ENABLED, things might take several hours (eg overnight) to get themselves right. It will then work as documented.


I added index.html in Default Root Object under General tab of cloudFront Distribution Settings and it worked for me. As index.html was the root file for my project!


In my case I was using multiple origins with "Path Pattern" Behaviors along with an Origin Path in my S3 bucket:

Bad setup:

CloudFront Behavior: /images/* -> My-S3-origin

My-S3-origin: Origin Path: /images

S3 files: /images/my-image.jpg

GET Request: /images/my-image.jpg -> 403

What was happening was the entire CloudFront GET request gets sent to the origin: /image/my-image.jpg prefixed by Origin Path: /images, so the request into S3 looks like /images/images/my-image.jpg which doesn't exist.

Solution

remove Origin Path.


Instead of choosing default s3 bucket for Origin Domain Name, please enter the <bucket-name>.s3-website.<region>.amazonaws.com as origin Domain Name(You can get this URL at Static website hosting property under S3 bucket properties).