Next Practical Step
Coordinate with your infrastructure team to obtain a test-bypass header or whitelist your load generator IP addresses.
Fix JMeter HTTP 429 Too Many Requests and WAF 403 Forbidden blocks. Handle Cloudflare, AWS WAF, rate limits, request pacing, and IP distribution.
During load ramp-up or sustained concurrency, requests suddenly start returning HTTP 429 or 403 status codes with security challenge HTML or JSON errors:
Response code: 429 (Too Many Requests)Response message: Rate limit exceeded. Try again in 60 seconds.Or when blocked by a Web Application Firewall (Cloudflare, AWS WAF, Akamai, Datadog):
Response code: 403 (Forbidden)Response message: Cloudflare Ray ID: ... / Access Denied by WAFSamplers pass during low-concurrency runs (1 thread) but fail consistently when concurrency or request rate scales up.
HTTP 429 means the target API rate limiter has capped your request frequency (e.g. 100 req/min per IP or API token). HTTP 403 WAF Block means an automated security rule detected JMeter’s default User-Agent signature, rapid connection patterns, or missing browser fingerprinting attributes.
| Cause | Status | Why it happens |
|---|---|---|
| IP-based API rate limiting | 429 | Hundreds of virtual users share a single injector IP address, triggering per-IP throttles (e.g. Nginx limit_req, Redis token buckets) |
| User / Token rate limiting | 429 | All threads use the same API key or Bearer token instead of parameterized test accounts |
| WAF bot detection | 403 | Cloudflare, Akamai, or AWS WAF blocks default Apache-HttpClient User-Agent string |
| Cloudflare Turnstile / CAPTCHA | 403 | Bot mitigation returns JS challenges or CAPTCHAs that headless HTTP samplers cannot compute |
| Aggressive burst rates | 429 | Lack of pacing timers generates unnatural millisecond bursts upon thread group start |
By default, JMeter sends User-Agent: Apache-HttpClient/.... Many WAFs block this header instantly. Add an HTTP Header Manager to your Test Plan with standard browser headers:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36Accept-Language: en-US,en;q=0.9Accept-Encoding: gzip, deflate, brFor performance testing in pre-production or staging environments:
X-Load-Test-Bypass: secret-token-from-devopsIf testing authenticated APIs with per-user rate limits:
Authorization: Bearer ${user_token}Avoid burst spikes that trigger rate limiters by smoothing traffic distribution:
<!-- Precise Throughput Timer in JMX --><PreciseThroughputTimer guiclass="TestBeanGUI" testclass="PreciseThroughputTimer" testname="Precise Throughput Timer"> <doubleProp name="throughput">50.0</doubleProp> <intProp name="throughputPeriod">1</intProp> <intProp name="duration">300</intProp></PreciseThroughputTimer>If per-IP rate limiting is a business requirement under test:
Source IP field in HTTP Request Defaults).| Resource | Use when |
|---|---|
| 401/403 after recording | Session tokens and credentials issues |
| Throughput stuck | Virtual users blocked from reaching target RPS |
| Distributed testing | Scaling load across multiple distinct IP addresses |
| Thread Calculator | Calculating required pacing and thread numbers |
Best practice is to test both: first, test the application directly (bypassing the WAF) to measure pure backend capacity and find application bottlenecks. Second, test through the WAF (with elevated rate limit rules) to measure WAF latency overhead and rule evaluation limits.
No. Standard JMeter HTTP samplers only parse network protocols, not client-side JavaScript execution. In staging environments, Cloudflare Turnstile should be disabled for test IPs or set to pass-through mode.