Troubleshooting "CloudFront Access Denied" Errors: A Step-by-Step Guide

Step 1: Disable Signed URLs or Signed Cookies

If you're using signed URLs or signed cookies, start by disabling them temporarily and testing access without them.

  • CloudFront blocks access when the signature is invalid or the key pair isn’t recognized.
  • Try serving the content publicly first to confirm whether the issue is related to signed authentication.
  • If access works without signed URLs, check your key pair and signature settings before re-enabling them.

Step 2: Check If CloudFront Can Access Your S3 Bucket

Even if your S3 bucket is publicly accessible, CloudFront requires explicit permissions. AWS offers two ways to allow CloudFront to access S3:

Option 1: Origin Access Control (OAC) (Preferred Method)

OAC is AWS’s latest method for securing S3 access. If you're using it, verify:

  • The CloudFront distribution is associated with the correct OAC.
  • The S3 bucket policy allows access from the OAC’s AWS principal.

Example S3 bucket policy for OAC:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceArn": "arn:aws:cloudfront::YOUR_AWS_ACCOUNT_ID:distribution/DISTRIBUTION_ID"
                }
            }
        }
    ]
}

Make sure to replace your-bucket-name, YOUR_AWS_ACCOUNT_ID, and DISTRIBUTION_ID with your actual values.

Option 2: Origin Access Identity (OAI) (Legacy Method)

If you’re still using OAI, confirm:

  • The OAI is attached to the CloudFront distribution.
  • The S3 bucket policy grants access to the OAI.

Example bucket policy for OAI:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR_OAI_ID"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

Replace YOUR_OAI_ID and your-bucket-name with the correct values.

If your CloudFront Access Denied error persists, move on to the next step.

Step 3: Check Your S3 Bucket Settings

Even with the correct CloudFront policies, certain S3 bucket settings can still block access.

Common S3 Settings That Cause Access Denied Errors

1. Requester Pays Setting

If Requester Pays is enabled on your bucket, CloudFront will automatically deny access because it doesn’t support this feature.

To check if it's enabled:

  • Go to Amazon S3 → Select your bucket
  • Navigate to Properties → Look for Requester Pays
  • If enabled, disable it and test again.

2. Public Access Block

AWS now blocks public access by default. If your bucket is still blocking CloudFront, ensure:

  • S3 Public Access Block settings allow objects to be served via CloudFront.
  • If using OAC or OAI, confirm no bucket-level policies contradict them.

3. Object Ownership Settings

CloudFront can return Access Denied if the objects are uploaded by another AWS account and you don’t have access.

  • Go to S3 bucket settingsObject Ownership
  • If it’s set to Bucket owner enforced, ensure that your IAM role has full access.

4. Disable AWS WAF

If you have AWS WAF enabled on the distribution try to disable it temporarily.

5. Check bucket region

Cloudfront distributions are single region (us-east-1) but support S3 buckets in different regions. Make sure that you are using the full region specific ARN to the bucket like otherwise Cloudfront will look in the bucket in the wrong region:

<bucket.name>.s3-website-<aws-region>.amazonaws.com

Step 4: Check CloudFront Cache Behavior & Distribution Settings

If your S3 permissions are correct but you still get an Access Denied, check CloudFront’s configuration:

1. Verify Cache Behavior

  • Ensure the Origin Request Policy allows S3 authentication headers (especially if using OAC).
  • If signed URLs are enabled, confirm the cache behavior enforces authentication correctly.

2. Check Origin Path & Bucket Name

  • The Origin Path should not contain the full bucket name (e.g., /my-bucket is incorrect).
  • The Origin Domain Name should be the S3 bucket name, not a custom domain.

3. Test With CloudFront Logs

Enable CloudFront logs to see the exact reason for access failure.

  • Go to CloudFront DistributionBehaviors
  • Enable Logging and check for specific error messages in CloudWatch.

Can also enable Cloudtrail with Data Events to check the error message when Cloudtrail calls S3 on your behalf.

Final Thoughts: Fixing CloudFront Access Denied the Right Way

Debugging CloudFront Access Denied errors can be tedious, but a structured approach will save you hours of frustration.

  1. Disable signed URLs/cookies and check if the issue is authentication-related.
  2. Ensure CloudFront has proper access via OAC or OAI and correct bucket policies.
  3. Verify S3 settings, especially Requester Pays, Public Access Block, and Object Ownership.
  4. Review CloudFront settings, making sure the Origin Path and Cache Behaviors align with your access setup.

By systematically following these steps, you’ll eliminate Access Denied errors and ensure seamless content delivery via CloudFront.

Getting Access Denied in AWS CloudFront? Read the article for tips

AWS CloudFront Access Denied might seem daunting but try debugging it step by step

Overwhelmed by AWS?

Struggling with infrastructure? We streamline your setup, strengthen security & optimize cloud costs so you can build great products.

Related AWS best practices blogs

Looking for more interesting AWS blog posts?

Abstracting Away from Object Storage Like S3 is Always a Good Idea

Abstracting away from object storage like S3 makes your development process more flexible, testable, and environment-agnostic.

Read more

Atlassian Does It Again: The Death of OpsGenie

Atlassian is shutting down OpsGenie, but the real question is: why were you using an Atlassian product to begin with?

Read more

Saving money with NAT instances and VPC endpoints

This article addresses the fact that AWS Managed NAT Gateways are expensive and provides solutions on how to save money on your AWS bill by using NAT instances and VPC endpoints.

Read more

IAM policy pitfalls

AWS has a lot of poor practices on their website. For instance if you look at the default Lambda execution role:

Read more

Manually fix your Terraform statefile in case of emergencies

The golden rule of infrastructure as code is not to change the infrastructure manually. However manual changes can happen by accident. Leaving the infrastructure in an inconsistent state.

Read more

Why CloudFront Signed URLs Are Better Than S3 Presigned URLs

Generate secure, long-lived URLs for S3 objects using CloudFront signed URLs, ensuring controlled expiration and improved security with OAC.

Read more

Why do S3 pre signed URLs expire after 12 hours, despite setting a longer duration?

S3 objects can be requested through a so called pre signed URLs, however the pre signed URL is tied to the identity that generated the URL. This means that if the credentials expire that generated thi ...

Read more

Why Your AWS ECS Task is Stuck in Pending—And What to Do About It

Troubleshooting AWS ECS tasks stuck in pending often reveals underlying infrastructure issues rather than ECS misconfigurations.

Read more

Why You Should Rethink AWS RDS Snapshots for Backups

Easily access RDS snapshots on S3 while avoiding common pitfalls—learn how to implement a flexible backup strategy beyond AWS snapshots.

Read more