AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
Why does AWS WAF block my request or respond with a 403 Forbidden error?
I want to identify the AWS WAF rule that blocks my request or responds with a 403 Forbidden error.
Short description
By default, AWS WAF returns a "403 Forbidden" error for requests that match AWS WAF rules with the Block action. If you set up custom responses for Block actions, then AWS WAF returns your configured response.
To troubleshoot the "403 Forbidden" error, use Sampled requests or AWS WAF logs. Identify the AWS WAF rule or rule group that blocks the request. Then, modify the rule to allow your request.
Resolution
Use sampled requests
If AWS WAF blocked your request within the past 3 hours, then you can view a sample of the blocked web requests. If AWS WAF blocked your request more than 3 hours ago, then resend the same request to generate a new sampled request.
In the Sampled requests table, review the following columns:
- To identify the request, review the Source IP and URI columns.
- To identify the rule or rule group that matches the request, review the Metric name column. If a rule group is blocking the request, then use the Rule inside rule group column to identify the rule.
- To confirm that the rule is set to Block, review the Action column.
Use AWS WAF logs
Note: If you didn't activate AWS WAF logging at the time of your request, then turn on AWS WAF logging and resend the same request.
Use the queries in your AWS WAF logs to identify the blocked requests. To query AWS WAF logs that you store in Amazon CloudWatch Logs, use Amazon CloudWatch Logs Insights queries. To query AWS WAF logs that you store in Amazon Simple Storage Service (Amazon S3), use Amazon Athena queries.
Query AWS WAF logs with CloudWatch Logs Insights
To get the top 10 terminating rules, run the following query:
fields terminatingRuleId | stats count() as requestCount by terminatingRuleId | sort requestCount desc | limit 10
To summarize requests that AWS WAF blocked by client IP address, country, URI, and rule, run the following query:
fields httpRequest.clientIp as ClientIP, httpRequest.country as Country, httpRequest.uri as URI, terminatingRuleId as Rule | filter action = "BLOCK" | stats count() as RequestCount by Country, ClientIP, URI, Rule | sort RequestCount desc
Note: In the output, the terminatingRuleId field identifies the AWS WAF rule or rule group that blocks the request.
Query AWS WAF logs with Athena
For AWS WAF logs that you store in an Amazon S3 bucket, use Athena to create an AWS WAF table that queries logs and filters details. For more information, see Query AWS WAF logs. Then, run queries on the table.
For example, to view the number of requests that AWS WAF blocked based on client IP address and country, run the following query:
SELECT "httprequest"."clientip" ,"count"(*) "count" , "httprequest"."country" FROM waf_logs WHERE ("action" LIKE 'BLOCK') GROUP BY "httprequest"."clientip", "httprequest"."country" ORDER BY "count" DESC
Identify the cause of a 403 from a single log entry
The previous CloudWatch Logs Insights queries return aggregated counts that help you find which rules block traffic. To inspect a single blocked request, run a query that returns raw log entries instead of aggregated counts. For example, to retrieve the most recent requests blocked by a specific rule, run the following query:
fields @timestamp, action, terminatingRuleId, httpRequest.clientIp, @message | filter action = "BLOCK" and terminatingRuleId = "RULE_NAME" | sort @timestamp desc | limit 20
Note: Replace RULE_NAME with a rule ID that appeared in the aggregated results. For example, AWS-AWSManagedRulesSQLiRuleSet. The @message field of each result is the full JSON log entry.
Review the following fields in the entry to identify the cause of the 403 response:
-
The Action field confirms that the request returned a 403 response when the value is Block.
-
The terminatingRuleId field shows the rule or rule group that matched and stopped evaluation.
-
The terminatingRuleType field indicates whether the match came from a MANAGED_RULE_GROUP, RATE_BASED rule, or REGULAR custom rule.
-
The terminatingRuleMatchDetails field shows the matched portion of the request for SQLi or XSS rules, including the location, condition type, and matched data.
-
The ruleGroupList field identifies the specific rule inside a managed rule group that produced the terminating action.
-
The Labels field contains labels that the rule or rule group attached to the request, which helps identify managed rule group matches.
-
The httpRequest.uri, httpRequest.args, and httpRequest.headers fields show the part of the request that the rule inspected.
The following example shows a log entry for a request that AWS WAF blocked. The AWS Managed Rules SQL database rule group matched a SQLi pattern in the query string:
{ "action": "BLOCK", "terminatingRuleId": "AWS-AWSManagedRulesSQLiRuleSet", "terminatingRuleType": "MANAGED_RULE_GROUP", "ruleGroupList": [{ "ruleGroupId": "AWS#AWSManagedRulesSQLiRuleSet", "terminatingRule": { "ruleId": "SQLi_QUERYARGUMENTS", "action": "BLOCK" } }], "terminatingRuleMatchDetails": [{ "conditionType": "SQL_INJECTION", "location": "QUERY_ARGUMENTS", "matchedData": ["'", "or", "1"] }], "httpRequest": { "clientIp": "203.0.113.42", "uri": "/products", "args": "id=1' OR '1'='1" } }
In this example, the terminatingRuleId is AWS-AWSManagedRulesSQLiRuleSet and the SQLi_QUERYARGUMENTS rule inside the rule group matched a SQL injection pattern. The terminatingRuleMatchDetails field shows that the match was in the query arguments and the matched tokens were ', or, and 1, which together appear in httpRequest.args (id=1' OR '1'='1).
The following example shows a log entry for a request that AWS WAF blocked. The source IP address is on the Amazon IP reputation list:
{ "action": "BLOCK", "terminatingRuleId": "AWS-AWSManagedRulesAmazonIpReputationList", "terminatingRuleType": "MANAGED_RULE_GROUP", "ruleGroupList": [{ "ruleGroupId": "AWS#AWSManagedRulesAmazonIpReputationList", "terminatingRule": { "ruleId": "AWSManagedIPReputationList", "action": "BLOCK" } }], "httpRequest": { "clientIp": "198.51.100.42", "uri": "/api/login" }, "labels": [ { "name": "awswaf:managed:aws:amazon-ip-list:AWSManagedIPReputationList" } ] }
In this example, the terminatingRuleId is AWS-AWSManagedRulesAmazonIpReputationList and the labels array confirms the match (awswaf:managed:aws:amazon-ip-list:AWSManagedIPReputationList). The source IP 198.51.100.42 appeared on Amazon's IP reputation list at the time of the request.
For requests blocked by a geo-match, rate-based, or custom rule, use the same approach. The terminatingRuleId combined with httpRequest.clientIp, httpRequest.country, and the labels array identifies which rule blocked the request and why.
Modify the AWS WAF rule to allow your request
If the blocking rule is in an AWS Managed Rules rule group, then customize the rule behavior.
If the blocking rule is a custom rule, then update your rule parameters to use a rule statement to allow the request.
Related information
How do I turn on AWS WAF logging and send logs to CloudWatch, Amazon S3, or Firehose?
- Tags
- AWS WAF
- Language
- English

This article was reviewed and updated on 2026-06-16.
Relevant content
asked a year ago
- Accepted Answer
asked 3 years ago
asked 2 years ago