apache/shenyu · error · RejectedExecutionException

Queue capacity is full.

Error message

Queue capacity is full.

What it means

ShenyuThreadPoolExecutor.execute() wraps the JDK executor: on RejectedExecutionException it retries offering the command into its TaskQueue with zero timeout; if retryOffer also fails, it throws RejectedExecutionException('Queue capacity is full.'). This means both the pool and the (possibly unbounded-seeming) queue refused the task — the EagerExecutorService has no free threads and the queue's retry path could not place the task.

Solutions

  1. Increase the queue capacity or maxPoolSize in the executor configuration.
  2. Throttle producers or add back-pressure (e.g. bounded submission with blocking wait).
  3. Check the wrapped cause 'e' for whether the executor was shutting down instead of full.
  4. Catch this RejectedExecutionException at the call site and queue/degrade the task (e.g. persist and retry later).

Example fix

// before
executor.execute(task); // throws when saturated
// after
try {
    executor.execute(task);
} catch (RejectedExecutionException ex) {
    fallbackQueue.add(task); // defer or persist for retry
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (executor.isShutdown() || executor.getQueue().remainingCapacity() == 0) {
    // shed or defer the task before calling execute
}

Try / catch

try {
    shenyuExecutor.execute(task);
} catch (RejectedExecutionException e) {
    LOG.warn("Pool and queue saturated, deferring task", e);
    deferred.add(task);
}

Prevention

When it happens

Trigger: execute(command) when all pool threads are busy, the queue rejects the initial offer, and queue.retryOffer(command, 0, MILLISECONDS) returns false — i.e. queue capacity truly exhausted or executor already terminated.

Common situations: Task submission rate exceeding pool+queue capacity; a small maxQueueCapacity configured for eager thread creation; shutdown racing with submissions.

Related errors


AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12). Data as JSON: /api/errors/37ac13a889b21385. Report an issue: GitHub.

Appendix: source

Thrown at shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/ShenyuThreadPoolExecutor.java:56

                                    final RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        workQueue.setExecutor(this);
    }

    @Override
    public void execute(final Runnable command) {
        if (Objects.isNull(command)) {
            throw new NullPointerException();
        }

        try {
            super.execute(command);
        } catch (RejectedExecutionException e) {
            // retry to offer the task into queue.
            final TaskQueue<Runnable> queue = (TaskQueue<Runnable>) super.getQueue();
            try {
                if (!queue.retryOffer(command, 0, TimeUnit.MILLISECONDS)) {
                    throw new RejectedExecutionException("Queue capacity is full.", e);
                }
            } catch (InterruptedException t) {
                throw new RejectedExecutionException(t);
            }
        }
    }
}

View on GitHub (pinned to 567142e072)