CloudFront 403 "The Request Could Not Be Satisfied": Every Cause, Fixed

Logeshwaran.C

If your visitors are hitting a gray page that says 403 ERROR — The request could not be satisfied. Request blocked. Generated by cloudfront (CloudFront), the fastest fix depends on which of three sub-messages you actually have — Bad Request, Request Blocked, or a plain Access Denied — because each one comes from a completely different setting, and CloudFront's own error page never tells you which. Here's the reveal that catches almost everyone: that page is not one error. It's a shared costume that at least seven unrelated problems wear, and two of the most common causes — a mismatched CNAME and a misconfigured AWS WAF rule — will show you the exact same wording as a private S3 bucket, so guessing from the screen alone sends people fixing the wrong thing for hours.

⚡ Quick Answer

Read the second line of the error page first. "Bad Request" → HTTP-vs-HTTPS or CNAME mismatch. "Request Blocked" → AWS WAF. No second line, just "Access Denied" → your origin (usually S3).

Fastest checkopen the distribution's General/Behaviors tab and match your exact wording against the table below.

Own an S3 origin and see "Access Denied" with no other text? Skip straight to the S3 section — it's the single most common cause of this whole family of errors.

Wait! if you are a new reader here and don't know about AWS because you didn't had money to learn or from Non Tech background, don't feel bad! I had create one hub, start from here: Learn AWS its free, and all in plain english so it will be easier for u to understand.. once its done come back here, it will be more easier..! Now, let's go back to topic and we will start as usual with Jake.


Jake called about this one on a Tuesday, which for Jake counts as an emergency, because Tuesday is when his shop's supplier catalog refreshes and a customer had just watched the whole page turn into a wall of AWS legal-sounding text on the showroom iPad. "It says 'the request could not be satisfied,'" he read out loud, like the internet had personally declined to help him. "Satisfied with what? I didn't ask it anything weird, I just opened the page." He hadn't touched a single AWS setting in four months. That's the part that throws people: a page that worked yesterday breaking today, with no code change on their side, almost always means a permission, a firewall rule, or a certificate did something in the background — not that anything is actually wrong with the website itself.

Ethan: "Picture CloudFront as a chain of front desks standing in front of your actual building. A visitor asks the nearest desk for a file. The desk doesn't own the building — it relays the request or hands over a copy it already holds. A 403 means the clerk said no, and there are exactly four reasons a clerk ever says no: the rulebook says block this (WAF), the clerk doesn't recognize the address you used (the CNAME and certificate family), the building itself refused the file (your origin, usually S3), or you didn't bring the badge the desk demands (signed URLs and cookies). Every fix here is figuring out which clerk you're arguing with."

Which 403 do you actually have?

CloudFront's default error page is one HTML template with a variable in the middle, and that variable is the whole diagnosis. Open the page (or ask whoever reported it for a screenshot — the exact wording matters more than anything else in this post) and match it here.

What the page says Most likely cause Jump to
"...Bad Request." Request came in over plain HTTP but the distribution only allows HTTPS, or the domain in the address bar isn't attached to any distribution Bad Request section
"...Request blocked." AWS WAF sits in front of the distribution and a rule (or the web ACL's default action) rejected the request Request Blocked section
Plain "Access Denied," often with XML tags, no extra sentence The origin itself refused the file — almost always a private S3 bucket without the right access control S3 origin section
"...not configured to allow the HTTP request method..." Your form or app sent POST/PUT/DELETE, but the behavior only allows GET/HEAD Invalid method section
403 only for visitors in one country, or after a promo went out Geographic restriction on the distribution Geographic restrictions section
403 only on private/paid content, everything else loads fine Signed URL or signed cookie missing, expired, or malformed Signed URLs section

‍♂️ Jake's Reality Check

"The page didn't say any of that. It just said 'Request blocked' and a Request ID that looks like a password nobody will ever type in."

That's normal — you're not missing extra text. The Request ID isn't diagnostic on its own; it's a lookup key for AWS support or your own CloudFront logs. What matters for you is the sentence above it, and "Request blocked" specifically only ever means one thing: AWS WAF. Skip straight to that section.

"Bad Request" — HTTP-only or a domain nobody attached

This exact wording only comes from one of two settings, and they're worth telling apart because the fix is different. Amazon's own troubleshooting documentation lists both causes for this specific "Bad Request" message: the request was made over plain HTTP while the distribution's viewer protocol policy only allows HTTPS, or the domain name typed in the browser (the alternate domain name, also called a CNAME) isn't associated with any CloudFront distribution at all.

Cause 1: someone typed http:// instead of https://

Old bookmarks, printed flyers, and QR codes from before you added HTTPS are the usual source. Check the behavior's viewer protocol policy: if it's set to HTTPS Only, a plain HTTP request gets this exact "Bad Request" page instead of the friendlier automatic redirect. That's a real, deliberate CloudFront setting, not a bug — some sites want a hard stop rather than a silent upgrade. If you'd rather the visitor just land on the secure page without seeing an error, change the viewer protocol policy to Redirect HTTP to HTTPS instead.

Cause 2: the CNAME isn't attached to this distribution

This one trips people who just bought a domain. The DNS record can point at the right CloudFront address and still fail, because CloudFront checks a second thing: does the distribution itself list that domain as an alternate domain name? If your DNS says "go to CloudFront" but no distribution says "I answer to this name," CloudFront has nowhere to route the request, and this is the message it returns.

  1. Open the distribution in the CloudFront console and check the Settings tab for Alternate domain name (CNAME). Your exact domain — including any subdomain — must be listed.
  2. If it's missing, add it, then attach a certificate from AWS Certificate Manager that covers that name (exact match or a wildcard at the same level).
  3. If it's already listed and you're still seeing this, confirm the DNS record actually points at this distribution's domain name and not an old one from a previous build.

Our walkthrough of putting a real domain and HTTPS in front of CloudFront covers the certificate-region rule that causes most of these mismatches — the short version is that CloudFront only reads certificates requested in the us-east-1 (N. Virginia) region, and a certificate anywhere else leaves the dropdown empty with no warning.

"Request Blocked" — AWS WAF is the bouncer, and it has a default answer

The word "Blocked" is the tell. This message only appears when AWS WAF — a firewall you can attach to a CloudFront distribution — sits between the visitor and your content and decides to reject the request. If you never set up WAF yourself, check anyway: it's often enabled by a template, a security review, or a colleague, and it's genuinely invisible from the distribution's main settings page unless you know to look at the Security tab.

AWS WAF runs on rules plus one default action, and the combination produces this error three distinct ways, per Amazon's own resolution guide:

Web ACL's default action What triggers the block
Allow The request matches a specific rule whose action is set to Block
Block The request matches a rule set to Block
Block The request doesn't match any rule set to Allow, so it falls through to the default

That third row is the one nobody expects: a web ACL whose default action is "Block everything unless a rule says otherwise" will silently reject perfectly normal visitors the moment a rule is slightly too narrow — a country you forgot to add, a user-agent string a legitimate crawler uses, a rate limit tuned for a quiet weekday that a Monday morning traffic bump exceeds.

  1. Open the CloudFront console, go to Distributions, and select the affected distribution.
  2. Choose the Security tab and click the link under Web Application Firewall (WAF) — this opens your web ACL in the WAF console, in a new tab.
  3. On the Rules tab, note the web ACL's default action at the top, then look at each rule's action.
  4. If the default action is Allow: find the rule matching your blocked requests and either narrow its condition or change specific traffic to Allow.
  5. If the default action is Block: your request needs to match an existing Allow rule, or you need to create one for it.

You don't have to guess which rule fired. The WAF console's sampled requests view (under the web ACL, in the same Rules area) shows a rolling sample of recent requests along with which rule matched each one — this is the fastest way to confirm the exact rule without trial and error.

✅ Why this is the one to check first

If your site was fine yesterday and broken today with zero code or content changes, WAF is the best first guess — of every cause in this post, it's the only one that a security team can silently switch on for the whole account without touching the distribution, the bucket, or a single line of your application.

Plain "Access Denied" — the S3 origin family of 403s

This is the most common cause of the whole family, and the plainest-looking one: a page with almost no text, sometimes literal XML tags reading Code, AccessDenied, Message, Access denied. It means CloudFront reached your S3 bucket and the bucket said no. AWS documentation lists five reasons this happens, and it's worth checking all five in order rather than assuming it's the first one you think of.

1. CloudFront doesn't have permission on the bucket

This happens when origin access control (OAC) or the older origin access identity (OAI) isn't enabled on the distribution, and the bucket itself is private — which, on any bucket created recently, it is by default. Without one of these, CloudFront is just an anonymous stranger asking S3 for a private file, and S3 correctly says no. Fix: enable OAC on the S3 origin (see the dedicated section below) and let CloudFront generate the bucket policy statement that grants it access, then paste that exact policy into the bucket.

2. The path in the URL is wrong

If you set an origin path on the S3 origin (for example, pointing CloudFront at a /production subfolder), the path the visitor requests has to line up with what's actually inside that subfolder — an origin path is prepended to every request CloudFront forwards, and a mismatch there returns exactly this error, not a helpful "folder doesn't exist" message.

3. The object genuinely isn't in the bucket

S3 returns Access Denied — not a 404 — for a missing object when the requester lacks s3:ListBucket, which CloudFront's origin setup deliberately omits for privacy. A typo'd filename, an unfinished deploy, or an upload to the wrong prefix all look exactly like a permissions problem. Check the object exists at the exact key before touching any policy.

4. The Host header got forwarded to a REST API endpoint origin

If your S3 origin uses the REST API endpoint format (bucket-name.s3.region.amazonaws.com, the correct choice for OAC) and your origin request policy forwards the viewer's Host header, S3 receives a request addressed to your custom domain instead of the bucket's own address and rejects it. This is functionally the same trap as the API Gateway Host-header issue covered in our custom-domain CloudFront build — the fix there is identical in spirit: don't forward the Host header to an origin that doesn't expect your domain name.

5. A custom error page is masking the real code

If you've configured a custom 403 error response that itself serves a static file with its own access problem, you end up staring at a second layer of the same error. Temporarily remove the custom error page for 403 and 404 while troubleshooting, so you're looking at CloudFront's raw response instead of your own replacement.

⚠️ What this actually breaks

S3 Block Public Access settings, at either the bucket or the whole account level, can override a bucket policy that otherwise looks perfectly correct — you can copy the exact policy CloudFront hands you, paste it in, and still get Access Denied if Block Public Access is fighting it. Check that setting before you re-read the policy for the fifth time.

OAC vs OAI — and the one case where only OAC works

Both origin access control (OAC) and the older origin access identity (OAI) exist to do the same job: let CloudFront read a private S3 bucket without making the bucket public. If you're setting this up for the first time, use OAC — it's the newer of the two and AWS's own guidance is direct about the one case where OAI simply cannot work.

  Origin access control (OAC) Origin access identity (OAI)
Serves objects encrypted with SSE-KMS Yes No — AWS documentation states OAI cannot serve KMS-encrypted objects at all
Which AWS recommends for new setups Yes, the current recommendation Legacy; still supported for existing distributions
Works with S3 website endpoints No — neither does. Both require the REST API endpoint No, same restriction

That last row catches a specific group: anyone who enabled S3 static website hosting and pointed CloudFront at the website endpoint (ending in s3-website-region.amazonaws.com) because an old tutorial said to. If that's your setup, OAC and OAI are both off the table — CloudFront treats it as a custom origin, not an S3 origin, and the bucket has to stay public. Switching to the REST API endpoint format is what unlocks OAC and lets you lock the bucket down.

  1. In the S3 origin's settings, confirm the Origin domain reads bucket-name.s3.region.amazonaws.com — not the website-hosting format.
  2. Under Origin access, choose Origin access control settings and create a new OAC (the defaults are fine for most setups).
  3. Save the distribution — CloudFront will show a banner offering to generate the matching bucket policy. Copy it.
  4. In the S3 console, open the bucket's Permissions tab, edit the bucket policy, and paste in the policy CloudFront gave you (don't hand-write your own version — a typo'd distribution ARN produces this exact error).
  5. Confirm Block all public access is still enabled — with OAC correctly configured, it should stay on, and the bucket never needs to be public.

"Not configured to allow the HTTP request method" — a form is the culprit

A slightly different sentence gets its own AWS documentation page and its own cause: this one appears specifically when a request uses a method CloudFront's behavior doesn't allow. Every CloudFront behavior has an Allowed HTTP Methods setting, and the default — GET and HEAD only — is deliberately restrictive, because a behavior that only ever needs to hand out cached files has no business accepting a POST.

The giveaway: it only happens on the endpoint your form, login page, or API call submits to, and only on submission — every other page loads fine because every other page is a plain GET. If your app sends POST, PUT, PATCH, or DELETE anywhere behind this distribution, open that behavior and change Allowed HTTP Methods to GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE. Leave the default alone on any behavior serving static assets — narrower is safer there.

A custom (non-S3) origin returning 403

If your origin is an EC2 instance, an Application Load Balancer, API Gateway, or any server you didn't build with S3, CloudFront isn't the one deciding to say no here — it's relaying a 403 your own server or gateway already produced. AWS's guidance is blunt about confirming this: make the same request directly to the origin, bypassing CloudFront. If the 403 reproduces without CloudFront in the picture, the origin is the source, and the fix lives in its own firewall or application code — not in CloudFront.

The one CloudFront-side cause worth checking first is the same Host-header issue from the S3 section, in its API Gateway form: CloudFront forwarding the viewer's domain in the Host header to an origin that only recognizes its own hostname. The fix is the origin request policy — use AllViewerExceptHostHeader instead of AllViewer.

Geographic restrictions

CloudFront lets a distribution allow-list or block-list entire countries, and a blocked visitor gets this same 403 family. It's easy to miss because it's set once and forgotten — check Distribution settings → Geographic restrictions if reports come only from specific countries, or started after a restriction was set for licensing reasons and the business later expanded into a newly blocked region. A support ticket from one region while everyone else is fine points here immediately.

Two honest caveats before you blame the setting. First, the block is decided by an IP-to-country lookup, and those databases are imperfect — a visitor on a VPN, a corporate network that routes traffic through another country, or a mobile carrier with oddly registered addresses can be "in" a blocked country while sitting in an allowed one, which is why geo complaints often arrive from people who insist, truthfully, that they are somewhere else. Second, the restriction applies to the whole distribution, not to individual pages — so if only some URLs fail from a region, geography is not your answer and you should move to the next section. The quick confirmation either way: test the URL through a VPN endpoint in the reported country; if it fails there and works from home, you have found your setting.

Signed URLs and signed cookies

If a behavior has Restrict Viewer Access turned on, CloudFront demands proof — a signed URL or a signed cookie — before it hands over anything, and a request without one, or with one expired, malformed, or built for a different path, gets this 403. This is correct behavior for paid downloads or subscriber content; the fix is checking what broke the signature: it expired (signatures carry a hard expiry timestamp), the signing key doesn't match the key group on the behavior, or the resource path doesn't exactly match — a signature scoped to /videos/* won't validate /videos/episode1/index.m3u8 unless that wildcard was included when it was generated.

Stacked distributions

This is the rarest cause in this post and the one AWS documentation actively warns against creating: one CloudFront distribution using another CloudFront distribution as its origin. AWS's guidance states plainly that placing one distribution in front of another returns a 403 and is not a recommended architecture. If you inherited a setup from a previous engineer and can't immediately tell what's origin and what's distribution, check each origin's domain name for anything ending in .cloudfront.net — that's the signature of a stacked setup, and the fix is architectural: point the outer distribution at the actual origin (the S3 bucket or server) instead of at the inner distribution.

Checked everything above and it's still 403? Do this

Three commands, run from a terminal, tell you more in thirty seconds than another hour of clicking through console tabs. They isolate which layer — DNS, certificate, WAF, or origin — is actually the one answering.

  1. Confirm what's actually answering. curl -sI https://yourdomain.com/ and read the x-cache header. "Error from cloudfront" means CloudFront itself generated the 403 (WAF, geo-restriction, or a CloudFront-side setting). A response with no CloudFront headers at all means the request never reached CloudFront — that's a DNS problem, not anything in this post.
  2. Bypass CloudFront and hit the origin directly. If it's S3, try the object's own bucket URL; if it's a server, hit its address directly. Still 403 there? The origin itself is the source (bucket policy, app firewall) and CloudFront is just relaying it honestly. Works fine there but not through CloudFront? The problem is definitely in the distribution's settings, not your origin.
  3. Force a fresh copy. If you fixed a policy or a WAF rule and you're still seeing the old error, CloudFront may be serving a cached error response. Open the distribution, go to Invalidations → Create, and invalidate /* — the first 1,000 paths a month don't add any charge.

One honest limit worth naming: if the 403 is coming from someone else's bucket, WAF, or server — you're a visitor, not the owner — none of the console steps here are available to you, because you can't open a console for infrastructure you don't run. The only real move is contacting the site, ideally with the Request ID from the error page, so their engineer can find the exact request in their own logs. If that's your situation, our plain-language guide to what cloudfront.net means and why sites block you is written for exactly that reader.

FAQ — CloudFront 403 errors, answered straight

What does "403 ERROR — The request could not be satisfied" mean?

CloudFront refused a specific request. The second line tells you why: "Bad Request" points to an HTTP/HTTPS or domain mismatch, "Request Blocked" points to AWS WAF, and plain "Access Denied" almost always points to the origin — usually a private S3 bucket.

Why does CloudFront say "Request blocked"?

Because AWS WAF is attached to the distribution, and either a specific rule or the web ACL's default action rejected the request. Check the Security tab on the distribution, open the linked web ACL, and review the default action and each rule's action.

Why does CloudFront say "Bad Request" instead of a specific reason?

This exact wording has two causes: the request arrived over plain HTTP while the behavior only allows HTTPS, or the domain typed in the browser isn't listed as an alternate domain name on any distribution. Check the viewer protocol policy first, then the Settings tab for alternate domain names.

Why do I get a 403 error from my S3 origin?

In order: OAC/OAI isn't enabled and the bucket is private; the origin path doesn't match the requested URL; the object doesn't exist at that key; the Host header was forwarded to a REST API endpoint origin; or S3 Block Public Access is overriding an otherwise-correct bucket policy.

What's the difference between OAC and OAI, and which one should I use?

Use origin access control (OAC) for any new setup. It's the current AWS recommendation and it's the only one of the two that can serve objects encrypted with SSE-KMS — origin access identity (OAI) cannot serve KMS-encrypted objects at all. Neither works with an S3 static website hosting endpoint; both require the REST API endpoint format.

Why does CloudFront return 403 for the root URL but individual pages work?

Usually a missing default root object combined with S3 not treating a trailing slash as a valid object name. Set a default root object (typically index.html) in the distribution's General settings, and confirm that file actually exists at the top level of the bucket or origin path.

Can AWS WAF cause a 403 even if I never wrote a rule to block anything?

Yes. If the web ACL's default action is set to Block, any request that doesn't match an existing Allow rule gets rejected automatically — you don't need a rule that explicitly targets the visitor for this to happen, you just need the absence of one that allows them.

How do I find out which WAF rule is blocking a specific request?

Open the web ACL in the AWS WAF console and use the sampled requests view under the Rules tab. It shows a rolling sample of recent requests along with the specific rule that matched each one, which is faster and more reliable than testing rule changes by trial and error.

Why does a signed URL or signed cookie return 403?

Three usual reasons: the signature has expired (signed URLs and cookies carry a hard expiry timestamp), the key used to sign it doesn't match the key group configured on the behavior, or the resource path in the signature doesn't exactly cover the path being requested.

Does a geographic restriction return a 403 or a 404?

A 403. CloudFront geographic restrictions block the request outright for visitors in a disallowed country rather than pretending the content doesn't exist, so a blocked visitor sees this same error page.

What is the "stacked distributions" error?

It's a 403 that happens when one CloudFront distribution is configured to use another CloudFront distribution as its origin. AWS documentation advises against this architecture entirely; the fix is pointing the outer distribution directly at the real origin instead of at the inner distribution.

Why do I get 403 for POST or PUT requests but GET works fine?

The behavior's Allowed HTTP Methods setting defaults to GET and HEAD only. Any endpoint that receives a form submission, a checkout, or an API write needs its Allowed HTTP Methods widened to include the methods your application actually sends.

My origin is a custom server, not S3 — why is CloudFront returning 403?

Make the same request directly to your origin's own address, bypassing CloudFront. If the 403 reproduces there, your server, load balancer, or API gateway is generating it, not CloudFront — check its own firewall or application logs. If it only happens through CloudFront, check whether the Host header is being forwarded to an origin that doesn't recognize your custom domain.

Does clearing the CloudFront cache (invalidation) fix a 403 error?

It fixes exactly one situation: you've already corrected the real cause (a policy, a WAF rule) and CloudFront is still serving a cached copy of the old error response. Invalidation never fixes the underlying permission, certificate, or firewall problem by itself.

Why did my site start returning 403 right after I added a custom domain?

Check whether the domain is listed as an alternate domain name on the distribution and whether the attached certificate covers it exactly, and check whether an origin request policy is forwarding the Host header to an origin (S3's REST endpoint, API Gateway) that only recognizes its own default hostname.

I'm just a visitor seeing this error on someone else's site — what should I do?

None of the console fixes in this post are available to you, because you don't own the distribution. Contact the site or app owner and include the Request ID shown on the error page so their engineer can find your exact request in their logs; there is nothing to fix on your own device.

Revision note. Written August 2026, covering CloudFront's current default error pages, AWS WAF's default-action logic, and origin access control (OAC) as the recommended replacement for origin access identity (OAI). This will need a revisit if AWS reorganizes the CloudFront console's Security tab or changes WAF's default behavior. If you're reading this at 11 p.m. with a client asking why the site is down and a page full of AWS jargon in front of you: you're closer than it feels — match the second line of the error to the table near the top, and you'll likely know which setting to open before this sentence finishes loading.

Related