Legitimate traffic getting rate-limited or banned
Telling apart the three things that can block a real user - sliding-window rate limit, auto-ban, threat-ban - and tuning each without disabling protection.
Three separate mechanisms can block a legitimate user, and they are tuned differently. Treating them as a single "blocking" problem leads to the wrong fix.
Symptom: real users hitting 429 or bans
A user reports being blocked. The dashboard shows activity from their IP. They are not an attacker.
Is it rate limit, auto-ban, or threat-ban?
| Mechanism | Response code | Trigger | Knob |
|---|---|---|---|
| Rate limit | 429 | Too many requests in the sliding window | rate_limit, rate_limit_window |
| Auto-ban | 403 | Strike counter (rate-limit + detections combined) over auto_ban_threshold | auto_ban_threshold, auto_ban_duration |
| Threat-ban | 403 | Detections of a specific attack class over the per-class threshold | threat_ban_config["<class>"] |
A 429 with no prior ban history is almost always a rate-limit issue. A 403 requires checking whether the IP was auto-banned via the shared strike counter or threat-banned via a detection class.
Reading the event to tell which
Open the Events page in the dashboard and filter by the affected IP. The event type tells you which mechanism fired:
rate_limit_exceeded- the sliding-window counter fired. The IP hit too many requests within the window.ip_bannedfollowing a trail ofrate_limit_exceededevents - the shared strike counter crossedauto_ban_threshold. Both rate-limit violations and detections contribute to this counter; an IP that trips the rate limiter repeatedly can accumulate enough strikes to escalate to a ban.ip_bannedwith no precedingrate_limit_exceededevents, or followingpenetration_attempt/behavioral_matchevents - athreat_ban_configper-class threshold was reached. Check the Redis ban record ({redis_prefix}banned_ips:{ip}) to confirm the ban is present and to inspect its TTL.
If the dashboard shows no events at all for the IP but the user reports 403, the IP may already be in the ban list from a previous window. Check Redis directly:
EXISTS {redis_prefix}banned_ips:{ip}
TTL {redis_prefix}banned_ips:{ip}See Rate limiting & auto-ban for the mechanics of each mechanism.
Tuning without disabling
Rate limit false positive - the user's traffic is legitimate but high-volume (a data-export job, a mobile app's background sync, a CI pipeline hitting your API).
Options:
- Raise
rate_limitorrate_limit_windowglobally, or add a per-route override with a higher limit for the affected endpoint. - For known high-volume IPs (internal services, trusted partners), a whitelist or per-route higher limit is more targeted than raising the global.
Do not disable rate limiting entirely. Per-route overrides let you raise limits on specific endpoints without changing the global posture. See Rate limiting & auto-ban.
Auto-ban false positive - the user is legitimately hitting the API frequently but not maliciously. The strike counter is shared between rate-limit violations and detections, so an IP that trips the rate limiter repeatedly can accumulate strikes and escalate to a ban.
Options:
- Raise
auto_ban_thresholdto require more strikes before a ban fires. - If the traffic pattern is expected (corporate NAT where many users share an IP, mobile CGNAT), raise both
rate_limitandauto_ban_thresholdtogether. - To unban immediately, delete the Redis key:
DEL {redis_prefix}banned_ips:{ip}. Note: the in-memory hot cache is not immediately invalidated, so the ban may persist on individual workers until the cache entry expires.
See Rate limiting & auto-ban for how rate-limit violations and detections share the strike counter.
Threat-ban false positive - a legitimate request triggered a detection pattern (a parameter value that resembles a SQLi probe, a path that matches file-inclusion patterns).
Options:
- Check the specific detection class in the event. Was it
file_inclusionfrom a honeypot path the user legitimately needs? Was itsqlifrom a search query with SQL-like syntax? - If a specific path should not trigger detection, use detection exclusions to exempt it.
- Adjust the
threat_ban_configthreshold for that class to require more detections before a ban, but only if you are confident the false-positive rate is high enough to justify it.
See Honeypots & threat-based banning for the difference between auto-ban and threat-ban and how each threshold works.
Geo or cloud block false positive
A 403 with no ban record in Redis and no event in the dashboard may be a geo or cloud block. These operate earlier in the pipeline and do not emit events to the dashboard.
Geo block: the user is connecting from a country in blocked_countries, or the route carries a decorator-level whitelist_countries and the user is outside it. A global whitelist_countries only exempts countries from the block list. It does not block the rest of the world on its own (see blocked_countries vs whitelist_countries). If the user's location is unexpected (VPN, travel, cloud-based development environment), they will hit the geo block.
Cloud block: block_cloud_providers contains the provider whose IP range the user's traffic originates from. Corporate offices that route through cloud-hosted proxies, or developers on cloud-based IDEs, can appear as cloud-originating traffic.
Options:
- Confirm the resolved client IP in the event, then look up the IP to confirm the geo or provider match.
- If the block is for a legitimate user, adjust
blocked_countries/whitelist_countriesor remove the offending provider fromblock_cloud_providers. - Note that
block_cloud_providersvalues are case-sensitive:"AWS","GCP","Azure". Lowercase or alternate forms are silently ignored.
See Geo + cloud-provider blocking for how each mechanism works and what each is appropriate for.
Related
- Rate limiting & auto-ban - rate limit mechanics, strike counter, ban storage and clearing
- Honeypots & threat-based banning - detection-class thresholds, threat-ban vs auto-ban
- Geo + cloud-provider blocking - country and provider block configuration