pinpoint-apm/pinpoint · warning · RequestNotPermittedException
max concurrent requests reached. table:<tableName>
Error message
max concurrent requests reached. table:<tableName>
What it means
RateLimiterPutWriter.acquire throws RequestNotPermittedException when the configured rate limiter cannot grant the requested number of permits for the put batch. It back-pressures writers so HBase write traffic stays under the configured request-per-second cap.
Source
Thrown at commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/async/RateLimiterPutWriter.java:64
try {
final List<CompletableFuture<Void>> results = this.putWriter.put(tableName, puts);
if (results != null) {
for (CompletableFuture<Void> result : results) {
result.whenComplete(release);
}
success = true;
}
return results;
} finally {
if (!success) {
this.limiter.release(size);
}
}
}
private void acquire(int size, TableName tableName) {
if (!this.limiter.acquire(size)) {
throw new RequestNotPermittedException("max concurrent requests reached. table:" + tableName, false);
}
}
@Override
public String toString() {
return "RateLimiterPutWriter{" +
"putWriter=" + putWriter +
", limiter=" + limiter +
'}';
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Raise the rate limiter configuration (permits per period) for the affected table
- Reduce put batch size or smooth the producer's write rate
- Catch RequestNotPermittedException at the caller and retry with backoff or queue the writes
- Verify multiple writers aren't each consuming the limit unexpectedly
Example fix
// before
putWriter.put(tableName, mutations); // throws on burst
// after
if (acquirePermits(batchSize)) { putWriter.put(tableName, mutations); } else { enqueueForRetry(mutations); } Defensive patterns
Strategy: try-catch
Validate before calling
// Query/config check before bulk writes
int maxPermits = rateLimiterConfig.getPermitsPerPeriod(tableName);
if (mutations.size() > maxPermits) {
logger.warn("Batch size {} exceeds rate limit {} for {}", mutations.size(), maxPermits, tableName);
} Try / catch
try {
putWriter.put(tableName, mutations);
} catch (RequestNotPermittedException e) {
logger.warn("Rate limited on {}, backing off: {}", tableName, e.getMessage());
retryQueue.offer(mutations); // or backoff+retry
} Prevention
- Size rate-limit config to your actual write throughput including bursts
- Break large mutation lists into smaller batches
- Add retry-with-backoff around put calls in collectors
- Monitor rate-limit rejections per table
When it happens
Trigger: Calling put (directly or via put(List)) when limiter.acquire(size) returns false because outstanding permits for the table already reach the configured max; large batch puts consume permits faster than the limiter replenishes.
Common situations: Burst write storms from collectors, oversized batch sizes relative to a low hbase.client.put-rate-limit setting, multiple collector instances sharing undersized limits.
Related errors
- invalid params
- traceReference is null
- traceReference is null
- cannot leave with BOUNDARY trace scope. depth: ${depth}
- Failed to get serviceUid. serviceName:${serviceName}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/c467e1e1719e3de4.
Report an issue: GitHub.