apache/dolphinscheduler · warning
Too many request, reach global rate limit, current global qp
Error message
Too many request, reach global rate limit, current global qps is {} What it means
RateLimitInterceptor.preHandle returns false with HTTP 429 when the global rate limiter has no permits (globalRateLimiter.tryAcquire fails) and trafficConfiguration.isGlobalSwitch() is on. This caps total API server QPS across all users/tokens.
Source
Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/RateLimitInterceptor.java:94
Object handler) throws ExecutionException {
// tenant-level rate limit
if (trafficConfiguration.isTenantSwitch()) {
final String token = request.getHeader("token");
if (StringUtils.isNotEmpty(token)) {
final RateLimiter tenantRateLimiter = tenantRateLimiterCache.get(token);
if (!tenantRateLimiter.tryAcquire()) {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
log.warn("Too many request, reach tenant token: {} rate limit, current tenant qps is {}",
MaskUtils.maskString(token, 6), tenantRateLimiter.getRate());
return false;
}
}
}
// global rate limit
if (trafficConfiguration.isGlobalSwitch()) {
if (!globalRateLimiter.tryAcquire()) {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
log.warn("Too many request, reach global rate limit, current global qps is {}",
globalRateLimiter.getRate());
return false;
}
}
return true;
}
public RateLimitInterceptor(ApiConfig.TrafficConfiguration trafficConfiguration) {
this.trafficConfiguration = trafficConfiguration;
if (trafficConfiguration.isGlobalSwitch()) {
this.globalRateLimiter =
RateLimiter.create(trafficConfiguration.getMaxGlobalQpsRate(), 1, TimeUnit.SECONDS);
}
}
}
View on GitHub (pinned to 02eac45a1b)
Solutions
- Increase global-max-qps in the traffic-control configuration to match server capacity.
- Add client-side throttling/backoff and spread scheduled API calls over time.
- Temporarily set global-switch=false if the limit is misconfigured and blocking production traffic.
- Scale out API servers and re-tune limits accordingly.
Example fix
// before global-switch=true global-max-qps=10 # whole cluster makes 100 req/s // after global-switch=true global-max-qps=200
Defensive patterns
Strategy: retry
Validate before calling
// central client semaphore sized below global-max-qps
from threading import BoundedSemaphore
import time
sem = BoundedSemaphore(50) # server global qps = 100
with sem:
time.sleep(1)
resp = api.call(...) Try / catch
for attempt in range(5):
resp = api.call(...)
if resp.status_code == 429: time.sleep(min(60, 2 ** attempt)); continue
break Prevention
- Set global-max-qps below total server capacity
- Spread batch jobs across time windows
- Add backoff in all API automation
- Alert on rising 429 counts at the load balancer
When it happens
Trigger: Aggregate API traffic from all clients exceeds the configured global QPS while global traffic control is enabled; preHandle logs the message and rejects with 429.
Common situations: Cluster-wide bursts (many schedulers, UI auto-refresh, mass workflow imports), load testing, a low global QPS default after enabling traffic control, thundering-herd after an outage.
Related errors
- Too many request, reach tenant token: {} rate limit, current
- USER_NO_OPERATION_PERM
- REQUEST_PARAMS_NOT_VALID_ERROR
- ACCESS_TOKEN_NOT_EXIST
- ALERT_GROUP_EXIST
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/c8c4506475e65ceb.
Report an issue: GitHub.