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

  1. Raise the rate limiter configuration (permits per period) for the affected table
  2. Reduce put batch size or smooth the producer's write rate
  3. Catch RequestNotPermittedException at the caller and retry with backoff or queue the writes
  4. 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

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


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/c467e1e1719e3de4. Report an issue: GitHub.