How to Fix 403 and 502 Errors on Azure Application Gateway v2
When a page shows 403 Forbidden or 502 Bad Gateway with Microsoft-Azure-Application-Gateway/v2 underneath, the error came from the Azure gateway in front of your servers, not from your application. A 403 almost always means the Web Application Firewall blocked the request, often a genuine visitor or an editor saving a page. A 502 means the gateway could not get a valid answer from any backend, usually because health probes, network rules or certificates have marked every server unhealthy. Both can lock out visitors and search crawlers at once. This guide shows you how to read the firewall and access logs, find the exact rule or backend fault, apply a narrow fix that keeps the protection in place, and confirm that the site answers normally again.
What the Azure Application Gateway error pages mean
Azure Application Gateway is a load balancer and reverse proxy that sits between visitors and your web servers. When it cannot or will not pass a request on, it answers itself with a plain error page that ends in the server name Microsoft-Azure-Application-Gateway/v2. That footer tells you something useful: the error came from the gateway, not from your application, so your application logs will often show nothing at all.
The two errors people search for most have quite different causes:
| Error | What the gateway is saying | Where the cause usually lives |
|---|---|---|
| 403 Forbidden | The Web Application Firewall (WAF) or an access rule decided this request is not allowed | WAF policy: managed rules, custom rules, geo or IP filters, bot protection |
| 502 Bad Gateway | The gateway tried to reach a backend and got no valid answer, or has no healthy backend to send to | Backend health: probes, network rules, certificates, timeouts |
| 504 Gateway Timeout | Seen on some set-ups when the backend is too slow | Backend performance and the request timeout setting |
A 403 from the gateway is the WAF doing its job, sometimes wrongly. A form post containing something that looks like SQL, a long cookie, or a content management system admin screen sending unusual parameters can all trigger a managed rule. In Prevention mode, a matched rule set that scores high enough blocks the request with a 403. In Detection mode, the same request is logged but allowed through.
A 502 almost always means that, from the gateway's point of view, the backend pool is unhealthy. The gateway sends health probes to every backend and only routes traffic to those that answer correctly. If every member fails the probe, every request gets a 502 even if the site works perfectly when you visit the server directly.
Common causes of 403 and 502 on Application Gateway v2
403 Forbidden causes
| Cause | Typical trigger | Fix |
|---|---|---|
| Managed rule false positive | Rich text editors, JSON bodies, search terms with quotes, long cookies from analytics | Add a targeted exclusion or disable the single rule for that path |
| Custom rule | An IP, geo or rate-limit rule with action Block | Correct the match condition or rule priority |
| Bot protection | Bot Manager rule set blocking a monitoring tool or a known crawler category | Allow-list your own tools by IP with a custom rule |
| Request size limit | Large uploads; this normally shows as 413 rather than 403 | Raise the body or file upload limit in the policy settings |
| Backend returning 403 | The application itself refuses the request; the response then carries the app's own page | Check the app, not the WAF |
502 Bad Gateway causes
| Cause | What you see in Backend health | Fix |
|---|---|---|
| Probe path returns an error or redirect outside 200 to 399 | Received invalid status code from the backend | Point the probe at a page that returns 200, or widen the match codes |
| Network security group blocks traffic | Unknown or unhealthy for every member | Allow GatewayManager on ports 65200 to 65535 and allow traffic from the gateway subnet to the backends |
| Backend certificate name mismatch | The Common Name of the backend certificate does not match the host header of the probe | Set the correct host name in the backend setting or probe |
| Backend certificate not trusted | The root certificate of the server certificate does not match the trusted root certificate | Use a public CA certificate on the backend or upload its root to the backend setting |
| Backend too slow | Healthy, but users still get 502 | Speed up the app or raise the request timeout, which defaults to 20 seconds |
| Custom DNS cannot resolve the backend | Backend address shown as unresolvable | Fix the VNet DNS servers or use the private IP address |
| Empty backend pool | No members listed | Add the servers or App Service back to the pool |
The timeout errors guide covers the slow backend case in more depth, because the fix is usually in the application rather than in Azure.
How to diagnose a 403 from the WAF
You need the WAF logs to see which rule fired. Without diagnostic settings the gateway keeps no record you can search, so turn them on first: open the Application Gateway in the Azure portal, choose Diagnostic settings, add a setting, tick the firewall log and the access log, and send them to a Log Analytics workspace. Reproduce the error after that, because earlier requests were not recorded.
Then open the workspace, choose Logs, and run a query. If your diagnostic setting uses the Azure diagnostics table, this lists recent firewall matches for your test IP address:
AzureDiagnostics
| where Category == "ApplicationGatewayFirewallLog"
| where clientIp_s == "203.0.113.25"
| where TimeGenerated > ago(1h)
| project TimeGenerated, requestUri_s, ruleId_s, action_s, Message, details_message_s, details_data_s, transactionId_g
| order by TimeGenerated descWith the resource-specific table option, the same data sits in AGWFirewallLogs with slightly different column names. Look at the rows that share one transaction ID. With anomaly scoring, several rules show as Matched, and a final row shows the request was Blocked once the total score passed the threshold. The Matched rows tell you which rules to deal with and details_data_s tells you what part of the request set them off, such as a cookie name or a form field.
How to diagnose a 502 Bad Gateway
Start with the Backend health page of the gateway in the portal. It lists every backend pool member, its status, and for unhealthy members a message that names the problem. The same information is available from the Azure CLI:
az network application-gateway show-backend-health \
--resource-group rg-example-web \
--name agw-example \
--query "backendAddressPools[].backendHttpSettingsCollection[].servers[].{address:address, health:health, log:healthProbeLog}" \
--output tableNext, check from inside the virtual network that the backend answers the probe the way the gateway expects. From a virtual machine in the same network, request the probe path with the host name the probe uses:
# Plain HTTP backend on a private IP, with the host header the probe sends
curl -sI -H "Host: www.example.com" http://10.0.2.4/health
# HTTPS backend: check the certificate name and chain the gateway will see
curl -svI --resolve www.example.com:443:10.0.2.4 https://www.example.com/health 2>&1 | grep -E "subject:|issuer:|HTTP/"The probe counts any status from 200 to 399 as healthy by default. A probe path that redirects to a login page off the site, or returns 401 or 404, marks the member as down. If the backend looks fine but users still get intermittent 502s, check the access log for the time taken and compare it with the request timeout in the backend setting. A response slower than that limit is cut off and returned as a 502.
AzureDiagnostics
| where Category == "ApplicationGatewayAccessLog"
| where httpStatus_d == 502
| where TimeGenerated > ago(1h)
| project TimeGenerated, requestUri_s, serverRouted_s, serverStatus_s, timeTaken_d
| order by timeTaken_d descAn empty serverStatus_s on 502 rows usually means the backend never answered at all, which points at network rules or a dead service rather than the application.
The key fixes
Fixing a WAF false positive with an exclusion
An exclusion tells the WAF to skip inspecting one named part of the request, for example a cookie or form field, while still checking everything else. In the WAF policy, open Managed rules, choose Exclusions, and add one. Where your rule set version supports it, scope the exclusion to the specific rule IDs from the log rather than to the whole rule set. For a rich text field called body on a blog editor that trips SQL injection rules, the exclusion would be: match variable Request arg names, operator Equals, selector body, applied to the rule IDs that fired.
If one rule fires on legitimate traffic across many fields, you can disable that single rule in the managed rule set instead. Prefer exclusions, because a disabled rule protects nothing anywhere on the site.
Allowing gateway traffic through the network security group
Application Gateway v2 needs inbound traffic from the GatewayManager service tag on ports 65200 to 65535 on its own subnet, plus traffic from the Azure load balancer. The backend subnet must accept the probe and request traffic from the gateway subnet.
az network nsg rule create \
--resource-group rg-example-web --nsg-name nsg-agw-subnet \
--name Allow-GatewayManager --priority 100 --direction Inbound \
--access Allow --protocol Tcp \
--source-address-prefixes GatewayManager \
--destination-port-ranges 65200-65535Fixing certificate and host name problems
For HTTPS backends, the gateway checks that the backend certificate is trusted and that its name matches the host name in the backend setting. If the backend uses a certificate from a public certificate authority, make sure the backend setting sends the right host: either enter the host name, such as www.example.com, or turn on Pick host name from backend target for App Service and other multi-tenant backends. If the backend uses an internal or self-signed certificate, upload its root certificate as a trusted root certificate in the backend setting. See the SSL host name mismatch guide for how the name check works.
Giving the probe a page that tells the truth
Create a custom probe pointing at a light page such as /health that returns 200 when the application can serve pages and an error when it cannot. Set the host name to match your site, and use an interval of 30 seconds with an unhealthy threshold of 3 as a sensible start.
A worked example
Example Bakery moves its WordPress site behind Application Gateway v2 with the WAF in Prevention mode. Two problems appear on launch day.
First, staff get 403 Forbidden, Microsoft-Azure-Application-Gateway/v2 every time they save a post that contains a recipe table. The firewall log query shows three Matched rows from SQL injection and cross-site scripting rules, all with details_data_s pointing at the post argument content on /wp-admin/post.php, followed by a Blocked row. Rather than disable the rules, the administrator adds a per-rule exclusion for the argument name content on those three rule IDs, and adds a custom rule that only allows /wp-admin from the office IP range. Saving works, and the admin area is better protected than before.
Second, the public site returns 502 Bad Gateway for all visitors. Backend health shows both servers as unhealthy with the message Received invalid status code from the backend. Visiting the servers directly works, so the administrator tests with curl from a VM in the same network, sending the host name the backend setting uses. The cause is that the backend setting overrides the host to the old staging domain, and the server answers 404 for that name. Correcting the host name in the backend setting and adding a custom probe on /health.txt turns both members healthy within a minute, and the 502s stop.
The fix, step by step
Step 1
Confirm the gateway sent the error
Look at the error page or run curl -sI against the failing URL and read the Server header or footer. If it says Microsoft-Azure-Application-Gateway/v2, the gateway produced the response and your application never saw the request. Note the exact URL, time, method and your public IP address, because you will need them to find the matching log rows. If the page shows your own site's design instead, the backend sent the error and you should check the application.
Step 2
Turn on diagnostic logs
In the Azure portal, open the Application Gateway, choose Diagnostic settings and add a setting that sends the access log and the firewall log to a Log Analytics workspace. Save it, wait a few minutes, then reproduce the 403 or 502 so it is recorded. Open the workspace, choose Logs and run a short query on the access log to confirm new rows are arriving before you start the deeper investigation.
Step 3
Find the WAF rule behind a 403
Query the firewall log for your IP address and the last hour, and group the rows by transaction ID. Note every rule ID marked Matched and the field named in the details data, such as a cookie or form argument. If no firewall rows exist for the request, the 403 came from a custom rule or from the backend instead. Write the rule IDs and field names down, because the exclusion in the next step needs them.
Step 4
Add a targeted exclusion
Open the WAF policy, choose Managed rules and then Exclusions, and add an exclusion for the exact field from the log, scoped to the rule IDs that fired where your rule set version allows it. Save the policy and wait for the update to finish. Repeat the request that was blocked; it should now succeed. Query the firewall log again to check the same transaction no longer ends with a Blocked row.
Step 5
Read Backend health for a 502
Open Backend health in the gateway, or run az network application-gateway show-backend-health, and read the status and message for each pool member. A message about invalid status codes points at the probe path or host name. Messages about certificates point at trust or name matching. Unknown or unhealthy for every member with no clear message usually points at a network security group or route table blocking traffic.
Step 6
Fix network rules and DNS
Check the network security group on the gateway subnet allows inbound TCP 65200 to 65535 from the GatewayManager service tag, and that the backend subnet allows traffic from the gateway subnet on the backend port. Remove any route on the gateway subnet that forces management traffic through another appliance. If backends use host names, confirm they resolve from the virtual network. Refresh Backend health and look for the status changing.
Step 7
Correct the probe and certificates
Create a custom probe on a light path such as /health with the right host name, and test it from a VM with curl -sI -H "Host: www.example.com". For HTTPS backends, make the backend setting send a host name that matches the backend certificate, or enable picking the host name from the backend target. Upload the root certificate if the backend uses an internal certificate authority, then check that every member shows Healthy.
Step 8
Check timeouts and retest from outside
If members are healthy but some requests still return 502, compare the slowest response times in the access log with the request timeout in the backend setting. Speed up the slow page or raise the timeout for that backend setting only. Finally, request your main pages from outside Azure with curl and run a crawl of the site, confirming that no 403 or 5xx responses remain for normal visitors and search crawlers.
Edge cases worth knowing
- Search engine crawlers being blocked. Bot protection and geo rules can block legitimate crawlers. If Search Console reports 403 for pages that load for you, check the firewall log for the crawler's requests. Our website 403 Forbidden guide covers how to confirm a crawler is being refused.
- A 403 that is really from the app. If the error page looks like your application's design rather than the plain gateway page, the WAF passed the request and the backend refused it.
- Intermittent 502s during deploys. If servers restart while still in the pool, the gateway routes to them until the probe marks them down. Use connection draining in the backend setting and deploy one member at a time.
- User-defined routes. A route table on the gateway subnet that sends internet traffic through a firewall appliance can break the gateway's own management traffic and probe results.
- Long uploads and websockets. Long-running requests can hit the request timeout. Raise it only for the backend setting that serves those paths.
- Outages and SEO. Long runs of 5xx errors slow Google's crawling. See Server error (5xx) in Search Console for what to do afterwards.
Keeping the gateway healthy
- Keep diagnostic logs flowing to Log Analytics at all times, so the next 403 or 502 can be traced in minutes rather than reproduced.
- Set an Azure Monitor alert on the Unhealthy Host Count metric above zero, and another on a rise in failed requests.
- Before turning on Prevention mode, run the WAF in Detection mode for a week of normal traffic, review the Matched rules, and add exclusions for genuine false positives first.
- Track backend certificate expiry dates and renew before they lapse, because an expired backend certificate makes every member unhealthy at once.
- Review exclusions and disabled rules every few months, and remove any that no longer apply.
- After any change, crawl the site from outside and look for 403 and 5xx responses. The HTTP error audit guide explains how to read the results.
1. How do I fix 403 Forbidden Microsoft-Azure-Application-Gateway/v2?
Find the WAF rule that blocked the request in the firewall log and add a narrow exclusion or adjust the rule, rather than turning the firewall off. Enable diagnostic settings so the firewall log reaches Log Analytics, reproduce the error, and query the log for your IP address. The rule IDs marked Matched and the field named in the details show what triggered the block. Then add an exclusion for that field on those rules, save the policy and test again.
2. How do I fix 502 Bad Gateway Microsoft-Azure-Application-Gateway/v2?
Open Backend health on the gateway and fix whatever is making the backend pool members unhealthy, because a 502 almost always means the gateway has no healthy backend to use. The message beside each member names the problem: a probe getting the wrong status code, a certificate whose name or root does not match, or no response at all, which usually means a network security group is blocking traffic. Once at least one member shows Healthy, the 502s stop.
3. Why does Application Gateway say my backend is unhealthy when the site works?
Because the gateway checks the backend in its own way, with its own probe path, host name and network route, and one of those differs from how you test it. Your browser may reach the site through a public address with the right host name, while the probe sends a different host header, uses HTTP instead of HTTPS, or is blocked by a network rule. Test the probe path from a VM in the same network with the same host header to see what the gateway sees.
4. Should I switch the WAF to Detection mode to stop 403 errors?
Only briefly, to confirm the WAF is the cause, and then switch it back to Prevention once you have added exclusions. In Detection mode the WAF logs matches but blocks nothing, so attacks such as SQL injection and cross-site scripting reach your application unchecked. A better long-term approach is to run Detection mode for a week before launch, review what matched on genuine traffic, add targeted exclusions for false positives, and then enable Prevention mode with confidence.
5. What ports does Application Gateway v2 need open?
Application Gateway v2 needs inbound TCP ports 65200 to 65535 open on its subnet from the GatewayManager service tag, which Azure uses to manage the gateway. It also needs traffic allowed from the Azure load balancer, and your listener ports such as 80 and 443 open for visitors. On the backend side, the servers must accept traffic from the gateway subnet on the port in the backend setting. A network security group that blocks any of these can leave every backend marked unhealthy.
6. Can the Azure WAF block Googlebot?
Yes, the WAF can block search engine crawlers if a custom rule, geo filter or bot protection setting catches them, or if a managed rule fires on a crawler request. When Search Console shows 403 errors for pages that open normally in your browser, query the firewall log for requests with a Googlebot user agent and see which rule acted. Verified good bots are normally allowed by the bot protection rule set, but custom rules run first and can override that.
7. Why do I get intermittent 502 errors on Application Gateway?
Intermittent 502s usually come from slow responses passing the request timeout, from servers restarting during a deploy while still in the pool, or from a backend that fails the probe now and then under load. Check the access log for the time taken on 502 rows and compare it with the timeout in the backend setting. Use connection draining and deploy one server at a time, and make sure the probe interval and threshold do not mark busy servers down too quickly.
Our HTTP error audit requests your pages from outside your network and lists every URL that returns a 403, 502 or other error, so you can see what visitors and crawlers are being refused.
Open HTTP Error Fixes โ