{"record":{"id":"37ac13a889b21385","repo":"apache/shenyu","slug":"queue-capacity-is-full","errorCode":null,"errorMessage":"Queue capacity is full.","messagePattern":"Queue capacity is full\\.","errorType":"exception","errorClass":"RejectedExecutionException","httpStatus":null,"severity":"error","filePath":"shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/ShenyuThreadPoolExecutor.java","lineNumber":56,"sourceCode":"                                    final RejectedExecutionHandler handler) {\n        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);\n        workQueue.setExecutor(this);\n    }\n\n    @Override\n    public void execute(final Runnable command) {\n        if (Objects.isNull(command)) {\n            throw new NullPointerException();\n        }\n\n        try {\n            super.execute(command);\n        } catch (RejectedExecutionException e) {\n            // retry to offer the task into queue.\n            final TaskQueue<Runnable> queue = (TaskQueue<Runnable>) super.getQueue();\n            try {\n                if (!queue.retryOffer(command, 0, TimeUnit.MILLISECONDS)) {\n                    throw new RejectedExecutionException(\"Queue capacity is full.\", e);\n                }\n            } catch (InterruptedException t) {\n                throw new RejectedExecutionException(t);\n            }\n        }\n    }\n}\n","sourceCodeStart":38,"sourceCodeEnd":64,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-common/src/main/java/org/apache/shenyu/common/concurrent/ShenyuThreadPoolExecutor.java#L38-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"Task submission rate exceeding pool+queue capacity; a small maxQueueCapacity configured for eager thread creation; shutdown racing with submissions.","solutions":["Increase the queue capacity or maxPoolSize in the executor configuration.","Throttle producers or add back-pressure (e.g. bounded submission with blocking wait).","Check the wrapped cause 'e' for whether the executor was shutting down instead of full.","Catch this RejectedExecutionException at the call site and queue/degrade the task (e.g. persist and retry later)."],"exampleFix":"// before\nexecutor.execute(task); // throws when saturated\n// after\ntry {\n    executor.execute(task);\n} catch (RejectedExecutionException ex) {\n    fallbackQueue.add(task); // defer or persist for retry\n}","handlingStrategy":"try-catch","validationCode":"if (executor.isShutdown() || executor.getQueue().remainingCapacity() == 0) {\n    // shed or defer the task before calling execute\n}","typeGuard":null,"tryCatchPattern":"try {\n    shenyuExecutor.execute(task);\n} catch (RejectedExecutionException e) {\n    LOG.warn(\"Pool and queue saturated, deferring task\", e);\n    deferred.add(task);\n}","preventionTips":["Match queue capacity and maxPoolSize to worst-case submission rates.","Alert on activeCount == maxPoolSize with a full queue.","Track executor shutdown state before submitting from background producers."],"tags":["concurrency","thread-pool","queue","backpressure"],"backgroundTag":"queue-capacity-exceeded","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}