Share via

WAF custom rule for rate limiting only blocking every other request once limit is reached.

Steven Bruce 0 Reputation points
2026-02-17T22:32:04.48+00:00

This is the rule that is being applied:
User's image

This is an example of the output:

User's image

Notice that the status codes alternate between 401 and 429. The rule is kicking in but does not persist. There are other articles that indicate others are observing this issue.

Is this a known issue? Is there the intention to fix it?

Azure Web Application Firewall
{count} votes

1 answer

Sort by: Most helpful
  1. David Broggy 6,796 Reputation points MVP Volunteer Moderator
    2026-02-17T22:53:39.9033333+00:00

    Hi Steven, that's how the DDoS works, it's a rate limiter, not a blocker.

    You will need an IP blacklist in order to do what you want.

    Instead of relying on WAF's inconsistent rate limit counter, you use two rules working together — your origin detects the abuse and signals the WAF, and the WAF's match rule (which has no distributed counter problem) does the blocking.

    Step 1 — Origin adds a response header when rate limit is hit

    In your application, track login attempts per IP. When an IP exceeds your threshold, add a custom header to the response, for example:

    X-Block-Client: true
    

    Your app already has consistent server-side state (Redis, memory cache, database), so this counter will be accurate.

    Step 2 — Create a WAF Match rule to block on that header

    In Azure Front Door WAF, create a second custom rule:

    • Rule type: Match (not Rate limit)
    • Priority: 0 (higher than your rate limit rule)
    • Condition:
      • Match variable: ResponseHeader
        • Header name: X-Block-Client
          • Operator: Contains
            • Match value: true
            • Action: Deny traffic (returns 429 or 403)

    Step 3 — Strip the header before it reaches the client

    Make sure Azure Front Door strips X-Block-Client from the response before it's sent to the end user, so you're not leaking internal signaling. You can do this via a Front Door Rules Engine action to remove the response header.

    Why this works better

    Match rules in Azure WAF evaluate a simple condition on the current request/response — there's no distributed counter involved, so the block is consistent on every single request once your origin has flagged that IP. The unreliable part (counting) moves into your application where you have full control over it.

    The main tradeoff is that the first ~20 requests (or however many your app allows) still reach your origin before the block kicks in. But that's actually fine for login protection — you want your app to be the authoritative source on whether an IP should be blocked, and the WAF then enforces it at the edge for all subsequent requests.

    Hope that helps.

    1 person found this answer helpful.

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.