AWS WAF 403 Forbidden — "Request blocked"
An AWS WAF rule matched the request and returned the default 403 block before it reached your application.
What you see
403 Forbidden Request blocked. (default AWS WAF block body served by CloudFront/ALB/API Gateway)
What’s actually happening
Requests get a 403 with a short "Request blocked" body, and nothing reaches your origin or application logs — the block happens at CloudFront, the ALB, or API Gateway where the web ACL is attached. It's often selective: a particular API call, a large POST, a request with a SQL-ish or HTML-ish query string, or traffic from one IP range. Legitimate clients get caught when a managed rule group fires on body content or headers that merely resemble an attack. Because the default block returns 403 with no rule name, the cause isn't obvious from the response alone.
Common causes
- An AWS Managed Rules group (e.g. Common Rule Set / SQLi / Known Bad Inputs) matched on a body, header, or query string that looks malicious but isn't.
- A rate-based rule tripped because the client exceeded the request threshold in the 5-minute window.
- An IP set or geo-match rule with a Block action covers the client's address or country.
- A size-constraint or body-inspection rule rejected an oversized upload or JSON payload.
- The web ACL's own default action is set to Block and no rule explicitly allowed the request.
How to fix it
- Find the terminating rule via sampled requestsIn the WAF console open your web ACL, go to the Sampled requests tab, and set Action = Block within the last 3 hours. The Metric/Rule name column shows which rule fired; if it's a group, the "Rule inside rule group" column names the specific sub-rule. If the block was older than 3 hours, resend the request to generate a fresh sample.
- Enable full WAF logging for detailTurn on web ACL logging to CloudWatch Logs, S3, or Firehose. The log records terminatingRuleId, terminatingRuleType, and the matched portion of the request, so you can see exactly which managed sub-rule and which field (body, URI, header) triggered the block.
- Tune the offending rule instead of disabling the groupFor a managed sub-rule false positive, override just that rule's action to Count (Rules > Edit > Override rule action) rather than removing the whole group. Add a scope-down statement or a label-match exclusion so the rule skips the specific path or content that's legitimate.
- Allowlist trusted sources with higher priorityCreate an IP set for your offices, partners, or load tests and add an Allow rule at a lower priority number (evaluated first) than the blocking rules. For rate-based blocks, raise the threshold or scope the rule to a single path like /login.
- Confirm the fix without weakening protectionAfter overriding to Count, watch the sampled requests/logs to verify the rule still matches the attack traffic but no longer blocks the legitimate request, then re-send the real request and confirm it returns 200. Keep the rule in Count only as long as needed to validate, then re-tighten.
Stop it recurring
Run new managed rule groups in Count mode first and watch the logs for false positives before flipping them to Block.