How to Troubleshoot Azure Web Application Firewall (WAF)

Microsoft Fix Advanced 14 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

You deployed Azure Web Application Firewall, your app went live, and now legitimate users are getting blocked. Or worse , something that should be blocked is sailing right through. I've seen this exact scenario on dozens of Azure environments, and the frustrating part is that Azure WAF's default error message , a bare 403 Forbidden with a cryptic match variable dump, tells you almost nothing actionable.

Azure WAF operates at two distinct deployment points: in front of Azure Application Gateway (layer 7, in your VNet) and in front of Azure Front Door (at Microsoft's global edge network). The rules engine, the log schema, and even some diagnostic behaviors differ between these two modes. A fix that works for Application Gateway WAF may not apply to Front Door WAF, that distinction trips up even experienced cloud engineers.

Here's what's actually going wrong when Azure Web Application Firewall misbehaves:

  • False positives from OWASP CRS rules, The default OWASP Core Rule Set (CRS 3.2 on Application Gateway, DRS 2.1 on Front Door) is aggressive. Rules like REQUEST-942-APPLICATION-ATTACK-SQLI can fire on totally benign query strings containing words like "select" or "union", a search box on an e-commerce site, for example.
  • WAF in Detection mode vs. Prevention mode, Many teams accidentally leave WAF in Detection mode after testing. Traffic flows through, violations are logged, but nothing is actually blocked. You think you're protected; you're not.
  • Misconfigured custom rules with incorrect match variables, A custom rule targeting RemoteAddr instead of SocketAddr will completely miss the source IP when your app sits behind a proxy or load balancer.
  • Exclusion rules that are too broad, An exclusion on RequestHeaderNames matching "Authorization" will disable inspection on that header globally, across every rule group. That's a significant security gap teams introduce while trying to fix one false positive in a hurry.
  • Log Analytics workspace not connected, Without diagnostic logs flowing to a workspace, you're flying blind. Azure WAF's native portal view shows almost nothing; the real data lives in AzureDiagnostics or the resource-specific WAFLogs table.
  • Rate limiting rules on Front Door WAF, The rate limit window is fixed at 1 minute. Teams expecting per-second rate limiting are surprised when bursts sail through before the counter trips.

Microsoft's own error messages in this space are notoriously unhelpful. A blocked request returns a 403, the default Azure WAF block page says "The request is blocked," and the requesting client gets zero diagnostic detail, by design, for security. But that means your support team and developers are also in the dark unless you've set up proper logging.

I know this is frustrating, especially when your app is in production and real users are affected. Let's get this sorted. Browse all Microsoft fix guides →

The Quick Fix, Try This First

The single fastest thing you can do when Azure Web Application Firewall is blocking legitimate traffic is to switch the WAF policy to Detection mode temporarily, identify the triggering rule ID from the logs, and create a targeted exclusion or custom rule override. Here's the express version:

1. Switch to Detection mode, In the Azure portal, navigate to Azure Application Gateway → Web application firewall → your WAF policy → Policy Settings. Change Policy mode from Prevention to Detection. Click Save. Now traffic flows through and violations are logged but not blocked, your users are unblocked immediately.

2. Reproduce the blocked request, Have the affected user repeat the exact action that triggered the 403. Capture the timestamp and, if possible, the x-azure-ref response header value, this is Azure WAF's unique transaction ID and makes log searching dramatically faster.

3. Query the logs, Open Log Analytics workspace → Logs and run:

AzureDiagnostics
| where ResourceType == "APPLICATIONGATEWAYS"
| where OperationName == "ApplicationGatewayFirewall"
| where action_s == "Matched" or action_s == "Blocked"
| project TimeGenerated, clientIp_s, requestUri_s, ruleId_s, ruleGroup_s, message_s, action_s
| order by TimeGenerated desc
| take 50

For Front Door WAF, use the AzureFrontDoorAccessLog and AzureFrontDoorFirewallLog tables instead. The field names differ slightly, look for ruleName_s and trackingReference_s.

4. Note the exact rule ID, Something like 942100 (SQL injection via libinjection) or 931130 (remote file inclusion). Take that rule ID straight to the WAF policy → Managed rules blade and disable just that rule, or add a scoped exclusion. Then flip back to Prevention mode.

This four-step loop solves probably 70% of Azure Web Application Firewall false positive issues in under 20 minutes.

Pro Tip
Before you disable or exclude any WAF rule, open the OWASP CRS documentation for that rule ID and understand what attack it's protecting against. Rule 942100 fires on SQL injection patterns, if you're disabling it because a search box uses the word "select," consider sanitizing that input on the application side instead of permanently lowering your WAF defenses. A targeted request attribute exclusion (scoped to just that URI path and that specific request body field) is always safer than disabling the rule outright.
1
Enable Diagnostic Logging and Connect a Log Analytics Workspace

Everything else in this guide depends on having good logs. If you skipped this step during initial setup, and many teams do, you're troubleshooting Azure Web Application Firewall completely blind.

In the Azure portal, go to your Application Gateway resource → Monitoring → Diagnostic settings. Click + Add diagnostic setting. Give it a name like waf-diagnostics-prod. Check these specific log categories:

  • ApplicationGatewayFirewallLog, this is the critical one, contains every WAF rule match and block decision
  • ApplicationGatewayAccessLog, request/response metadata including backend pool hits
  • ApplicationGatewayPerformanceLog, throughput and latency data

Under Destination details, check Send to Log Analytics workspace and select your workspace. If you don't have one, create it now, it's a few clicks and a few dollars a month, and it pays for itself the first time you need to diagnose a WAF issue. Click Save.

For Front Door WAF, the path is: Azure Front Door profile → Monitoring → Diagnostic settings, and you want FrontDoorFirewallLog and FrontDoorAccessLog.

Give logs 10–15 minutes to start flowing, then verify with this KQL query:

AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| take 10

If rows come back, you're good. If not, double-check the diagnostic setting saved correctly and that the workspace is in the same subscription (cross-subscription workspace sends can fail silently without proper permissions).

2
Identify Blocked Requests Using WAF Log Queries

Now that logs are flowing, let's find exactly what Azure Web Application Firewall is blocking. The action_s field is your primary filter, values are Matched (Detection mode, or non-blocking rules), Blocked (Prevention mode, rule fired and blocked), and Detected (anomaly scoring threshold not yet reached).

Run this query in Log Analytics to get a summary of your top blocked rule IDs over the last 24 hours:

AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| where TimeGenerated > ago(24h)
| where action_s == "Blocked"
| summarize BlockCount = count() by ruleId_s, ruleGroup_s, requestUri_s
| order by BlockCount desc
| take 20

This gives you a ranked list. If rule 942430 (Restricted SQL Character Anomaly Detection) is blocking 500 requests a day from legitimate users hitting your search endpoint, that's your smoking gun.

To investigate a specific client IP that's complaining they're blocked:

AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| where clientIp_s == "203.0.113.45"
| where TimeGenerated > ago(1h)
| project TimeGenerated, requestUri_s, ruleId_s, ruleGroup_s, message_s, action_s, matchVariableName_s, matchVariableValue_s
| order by TimeGenerated desc

Pay close attention to matchVariableName_s and matchVariableValue_s. These fields tell you exactly which part of the request triggered the rule, a specific request header, a cookie name, a query string parameter, or a field in the POST body. That's the information you need to write a surgical exclusion rule rather than a broad one. If the WAF logged that rule 920230 matched on the RequestHeaderNames variable with value x-custom-auth, you know to scope your exclusion to that exact header.

3
Create Targeted Exclusion Rules for False Positives

Once you've identified the specific rule and match variable causing the false positive, create a scoped exclusion, not a full rule disable. There's a big difference. Disabling rule 942100 removes SQL injection protection across your entire application. An exclusion scoped to RequestBodyPostArgNames Equals "searchQuery" removes protection only for that one POST parameter, everything else stays inspected.

In the portal: WAF policy → Managed rules → Exclusions → + Add exclusion.

The exclusion form has three fields that work together:

  • Match variable, what part of the request to exclude (e.g., RequestBodyPostArgNames)
  • Operator, how to match (e.g., Equals, StartsWith, Contains)
  • Selector, the specific value (e.g., searchQuery)

You can also do this via PowerShell, which is better for repeatable deployments:

$exclusion = New-AzApplicationGatewayFirewallExclusion `
    -MatchVariable "RequestBodyPostArgNames" `
    -SelectorMatchOperator "Equals" `
    -Selector "searchQuery"

$wafConfig = Get-AzApplicationGatewayWebApplicationFirewallConfiguration `
    -ApplicationGateway $appGw

$wafConfig.Exclusions.Add($exclusion)

Set-AzApplicationGateway -ApplicationGateway $appGw

After saving, switch back to Prevention mode and retest. The legitimate request should now pass through while the WAF still inspects every other part of the request. If you're still seeing blocks, it means another rule is also matching, go back to your logs and check for additional Matched entries on the same request timestamp.

4
Fix Custom Rule Logic Errors

Custom rules in Azure Web Application Firewall are processed before managed rules and can both allow and block traffic. Logic errors here are common, especially around IP-based rules, and they can silently break your entire WAF policy.

The most common mistake I see: using RemoteAddr as the match variable to block or allow IP ranges when the app sits behind Azure Front Door or another reverse proxy. RemoteAddr in that scenario is always the proxy's IP, not the real client. Use SocketAddr for the actual connecting IP, or RequestHeaders matching X-Forwarded-For if your infrastructure populates that header.

Another frequent problem: custom rule priority conflicts. Custom rules are evaluated in ascending priority order (lower number = higher priority). If you have an Allow rule at priority 10 for your office IP range and a Block rule at priority 5 for a threat feed, the block fires first and your office gets locked out. Review your rule priority order in WAF policy → Custom rules and sort carefully.

To audit all custom rules via PowerShell:

$policy = Get-AzApplicationGatewayFirewallPolicy -Name "myWAFPolicy" -ResourceGroupName "myRG"
$policy.CustomRules | Select-Object Name, Priority, RuleType, Action | Sort-Object Priority

Also check your custom rule conditions carefully. The IPMatch operator requires CIDR notation, writing 192.168.1.1 instead of 192.168.1.1/32 will cause the rule to fail silently and not match anything. Always use CIDR, even for single IPs.

After making changes, test with a request from a known IP in your allow/block list and verify in the logs that the correct action (Allow or Block) shows with your custom rule name in ruleId_s.

5
Validate WAF Policy Association and Rule Set Version

Sometimes Azure Web Application Firewall simply isn't doing anything because the policy isn't actually associated with the right resource, or it's associated but the wrong policy is active. This sounds basic, but I've seen it cause hours of confusion.

For Application Gateway WAF: Navigate to your Application Gateway → Web application firewall blade. Under Associated WAF policy, confirm the correct policy name is shown and its status shows as Succeeded. If it shows as Not associated or references an old policy name, click Associate WAF policy and select the correct one.

For Front Door WAF: Go to Azure Front Door profile → Security → WAF policies. Each domain association must be explicitly linked. A policy exists but isn't protecting traffic until it's associated with one or more domains.

While you're here, check your rule set version. Application Gateway WAF defaults can be on CRS 3.1, which is significantly older than CRS 3.2 (released with better anomaly scoring, fewer false positives, and improved SQLi detection). Front Door WAF defaults may be on DRS 1.1 when DRS 2.1 is available. Upgrading the rule set version fixes a lot of false positive problems for free.

To upgrade via Azure CLI:

az network application-gateway waf-policy managed-rule rule-set add \
    --policy-name myWAFPolicy \
    --resource-group myRG \
    --type OWASP \
    --version 3.2

After updating, monitor your WAF logs closely for the first 48 hours, rule set upgrades can sometimes introduce new false positives for your specific application, especially in rule group REQUEST-920-PROTOCOL-ENFORCEMENT. Have your Log Analytics dashboard open and know how to quickly add an exclusion if needed.

Advanced Troubleshooting

If the step-by-step fixes above haven't resolved your Azure Web Application Firewall issue, we need to go deeper. Here's what I look at when the obvious fixes haven't worked.

Anomaly Scoring Mode vs. Classic Mode

Application Gateway WAF CRS 3.2 introduced anomaly scoring, instead of blocking on the first matched rule, each matched rule adds to a cumulative anomaly score. When the score exceeds the threshold (default: 5 for block, 3 for log), the request is blocked. This is great for reducing false positives but it changes how you interpret logs. In anomaly scoring mode, a request might match 4 rules at score 1 each, the final block entry in the log shows the rule that pushed it over the threshold, not all four contributing rules. Always query for all log entries across a 1-second window for the same client IP to see the full picture.

Event Viewer and Activity Log Analysis

For Application Gateway WAF configuration changes that don't seem to take effect, check the Azure Activity Log: Application Gateway → Activity log. Filter by Operation = Update ApplicationGateway. A failed update (red status) means your last WAF policy change didn't deploy, usually due to a conflicting operation already in progress or a validation error. The Status message field in the failed operation entry will have the specific error reason.

Group Policy and Azure Policy Interference

In enterprise environments, Azure Policy assignments can prevent WAF policy changes. If you're getting RequestDisallowedByPolicy errors when trying to modify WAF settings, run:

az policy state list \
    --resource "/subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.Network/applicationGateways/{gwName}" \
    --query "[?complianceState=='NonCompliant']" \
    --output table

This shows you exactly which policy assignment is blocking the change. Common culprits: policies requiring WAF to be in Prevention mode (blocking your temporary switch to Detection), policies enforcing specific rule set versions, or policies denying WAF exclusions entirely for compliance reasons.

Network-Level Inspection with Packet Capture

If you suspect the WAF is making decisions based on malformed or manipulated headers, use Application Gateway's built-in packet capture: Application Gateway → Support + troubleshooting → Packet capture. Start a 5-minute capture scoped to your WAF frontend IP. Download the resulting .pcap file and open it in Wireshark. Filter on http.response.code == 403 to see blocked transactions with full request headers. This reveals issues like double-encoded characters in URLs (%2527 = double-encoded single quote) that trigger WAF rules but are invisible in the portal logs.

WAF Capacity and Performance Issues

Azure WAF on Application Gateway v2 uses autoscaling, but WAF inspection adds latency, typically 1–5ms for clean traffic, but up to 50ms for large POST bodies being fully inspected. If you're seeing latency spikes, check Application Gateway → Metrics → Application Gateway Total Time split by WAF Processing Time. If WAF is consuming more than 20% of total request time consistently, consider enabling the MaxRequestBodySizeInKb limit (default 128KB) to reduce inspection scope for large file uploads, or enable file upload exclusions for specific URI paths.

When to Call Microsoft Support
Escalate to Microsoft Support when: (1) your WAF policy shows Succeeded in the portal but is demonstrably not inspecting traffic despite correct association; (2) you're seeing rule IDs in WAF logs that don't exist in the published OWASP CRS or DRS documentation, this can indicate a platform-level rule set issue; (3) your Application Gateway is in an inconsistent provisioning state (az network application-gateway show returns provisioningState: Failed) and standard portal operations won't resolve it; or (4) you're on a support plan and experiencing a live production outage affecting revenue. Have your subscription ID, resource group name, Application Gateway resource ID, and the relevant Log Analytics query results ready before you open the ticket, it cuts resolution time significantly.

Prevention & Best Practices

Most Azure Web Application Firewall issues are preventable with the right setup from day one. Having done dozens of WAF deployments and post-incident reviews, here's what actually keeps things running smoothly.

Test in Detection mode before going to Prevention mode. Deploy your WAF policy in Detection mode, run your full regression test suite against the application, and spend at least one week in production letting real traffic generate logs. Query for all action_s == "Matched" entries, triage them into true positives and false positives, create exclusions for the false positives, and only then switch to Prevention. Teams that skip this step always end up emergency-switching back to Detection mode on a Friday afternoon.

Version your WAF policies as infrastructure-as-code. Define your WAF policies in Bicep or Terraform, not through the portal. When you click-to-configure in the portal, nobody knows what changed, when, or why. With IaC, every rule add, every exclusion, every mode change is a git commit with a PR and a review. This single practice eliminates an entire class of "why is WAF suddenly blocking X" incidents caused by someone making an undocumented portal change.

Set up alerting on blocked request spikes. In Azure Monitor, create an alert rule on AzureDiagnostics | where action_s == "Blocked" | summarize count() with a threshold that fires when blocks exceed your baseline by more than 50% in a 15-minute window. A sudden spike in Azure Web Application Firewall blocks is either an attack (good, WAF is working) or a deployment that broke something (bad, needs immediate exclusion). Either way, you want to know about it in real time, not from a user complaint an hour later.

Document your exclusions with business justification. Every WAF exclusion should have a comment explaining why it exists. "Exclusion for rule 942100, POST body field 'sqlSearchTerm' on /api/reports triggers false positive due to legitimate SQL-like syntax in report builder queries." Without this documentation, nobody knows if an exclusion from 18 months ago is still needed or is a gaping security hole.

Quick Wins
  • Upgrade to CRS 3.2 (Application Gateway) or DRS 2.1 (Front Door) immediately, both have significantly fewer false positives than their predecessors
  • Enable WAF diagnostic logs to Log Analytics before you need them, not after an incident forces you to
  • Use the x-azure-ref response header in your application's error pages so support teams can search logs directly by transaction ID
  • Review and clean up WAF exclusions quarterly, exclusions added during incidents often outlive the reason they were created

Frequently Asked Questions

Why is Azure WAF blocking my legitimate API calls with a 403 error?

The most common culprit is an OWASP CRS rule matching on the content of your request body or headers, particularly rules in the REQUEST-942-APPLICATION-ATTACK-SQLI or REQUEST-941-APPLICATION-ATTACK-XSS groups. API payloads with JSON fields containing characters like single quotes, angle brackets, or SQL-like keywords trip these rules constantly. Pull your WAF logs from Log Analytics, find the specific rule ID and match variable, and create a scoped exclusion for that request attribute. If your API traffic consistently triggers WAF rules that don't apply (e.g., your app processes financial data with SQL-like field names), consider creating a separate WAF policy in Detection mode for those specific API routes while keeping Prevention mode on your web frontend routes.

Azure WAF is in Prevention mode but traffic isn't being blocked, why?

First, verify the WAF policy is actually associated with your Application Gateway or Front Door resource, go to the WAF policy blade and check the Associated resources section. A policy that exists but isn't associated does nothing. Second, confirm you're looking at the right resource, it's common in multi-region setups to have updated the WAF policy on the West Europe gateway but not the East US one. Third, check if an existing allow custom rule with a low priority number is matching your traffic before the managed rules get evaluated, custom rules always run before managed rules. Finally, check that State is set to Enabled on the WAF policy itself, not just the mode set to Prevention.

How do I find out exactly which WAF rule blocked a specific request?

The fastest path is the x-azure-ref header in the 403 response, if the client captures it, you can search directly: AzureDiagnostics | where requestUri_s contains "yourPath" | where TimeGenerated between (datetime(2026-04-21 14:30) .. datetime(2026-04-21 14:35)). Look at the ruleId_s, ruleGroup_s, matchVariableName_s, and matchVariableValue_s fields, together they tell you the rule that fired, which rule group it belongs to, what part of the request matched, and the exact value that triggered it. In anomaly scoring mode on CRS 3.2, query a 1-second window around the block to catch all contributing matched rules, not just the final blocking entry.

Can I whitelist a specific IP address to bypass Azure WAF completely?

Yes, create a custom rule with action Allow, match variable SocketAddr, operator IPMatch, and your IP range in CIDR format (e.g., 203.0.113.10/32). Set the priority to a low number like 1 so it evaluates before all other rules. When this rule matches, Azure WAF skips all managed rules and passes the request directly to the backend. That said, think carefully before doing this, a whitelisted IP still passes through but receives zero WAF inspection. If that IP is ever compromised or spoofed, your application is wide open from that source. A better approach for internal tools is to use managed identities and application-level authentication rather than IP allowlisting at the WAF layer.

What's the difference between Azure WAF on Application Gateway vs. Azure WAF on Front Door?

Application Gateway WAF runs inside your Virtual Network, operates at OSI layer 7, and is typically used to protect internal or regionally-deployed applications. It supports CRS rule sets and terminates SSL/TLS within your VNet. Front Door WAF operates at Microsoft's global edge points of presence, over 200 locations worldwide, and inspects traffic before it even reaches your Azure region, which means DDoS protection and latency reduction happen at the same layer as WAF inspection. Front Door WAF uses DRS (Default Rule Sets) derived from OWASP but extended by Microsoft, and it adds capabilities like bot protection rules and JavaScript challenge actions that Application Gateway WAF doesn't support. The log schemas, PowerShell cmdlets, and some configuration options differ between the two, so troubleshooting steps that work for one may not apply directly to the other.

My WAF exclusion isn't working, the same rule is still blocking requests after I added the exclusion. What's wrong?

The most common mistake is specifying the wrong Match variable in the exclusion. If your logs show the rule matched on RequestBodyPostArgNames with value userInput, your exclusion must also target RequestBodyPostArgNames with selector userInput, not RequestBody or RequestBodyContents, which are different variables. Double-check this by going back to your WAF logs and reading the matchVariableName_s field exactly as it appears. Also check if multiple rules are matching the same request, exclusions apply to specific rules, so if your exclusion targets rule 942100 but rule 942110 is also matching on the same field, the second rule will still block. Query your logs for all matched rules in a 1-second window for that client IP and create an exclusion for each contributing rule.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.