Netflix/Hystrix · warning · RejectedExecutionException

Rejected command because thread-pool queueSize is at rejecti

Error message

Rejected command because thread-pool queueSize is at rejection threshold.

What it means

When a HystrixCommand runs with thread isolation, work is scheduled through HystrixContextScheduler. Before handing a task to the worker, the scheduler checks HystrixThreadPool.isQueueSpaceAvailable(); when the pool's queue has reached its rejection threshold (queueSizeRejectionThreshold), this RejectedExecutionException is thrown. Hystrix translates it into a THREAD_POOL_REJECTED / fallback outcome rather than a crash.

Source

Thrown at hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixContextScheduler.java:93

        private HystrixContextSchedulerWorker(Worker actualWorker) {
            this.worker = actualWorker;
        }

        @Override
        public void unsubscribe() {
            worker.unsubscribe();
        }

        @Override
        public boolean isUnsubscribed() {
            return worker.isUnsubscribed();
        }

        @Override
        public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
            if (threadPool != null) {
                if (!threadPool.isQueueSpaceAvailable()) {
                    throw new RejectedExecutionException("Rejected command because thread-pool queueSize is at rejection threshold.");
                }
            }
            return worker.schedule(new HystrixContextSchedulerAction(concurrencyStrategy, action), delayTime, unit);
        }

        @Override
        public Subscription schedule(Action0 action) {
            if (threadPool != null) {
                if (!threadPool.isQueueSpaceAvailable()) {
                    throw new RejectedExecutionException("Rejected command because thread-pool queueSize is at rejection threshold.");
                }
            }
            return worker.schedule(new HystrixContextSchedulerAction(concurrencyStrategy, action));
        }

    }

    private static class ThreadPoolScheduler extends Scheduler {

View on GitHub (pinned to 5ce3bc58c3)

Solutions

  1. Tune the pool: raise corePoolSize/maximumSize and queueSizeRejectionThreshold via hystrix.threadpool.<key>.coreSize / maximumSize / maxQueueSize / queueSizeRejectionThreshold properties.
  2. Reduce command execution time or move blocking work out of run() so pool threads free up faster.
  3. Implement a getFallback() so rejections degrade gracefully instead of propagating failure.
  4. Shed load upstream (rate limiting, bulkheading at the caller) so fewer tasks reach a saturated pool.

Example fix

# before
hystrix.threadpool.orders.coreSize=10
hystrix.threadpool.orders.maxQueueSize=-1

# after
hystrix.threadpool.orders.coreSize=25
hystrix.threadpool.orders.maximumSize=40
hystrix.threadpool.orders.maxQueueSize=100
hystrix.threadpool.orders.queueSizeRejectionThreshold=50
Defensive patterns

Strategy: fallback

Validate before calling

// Check saturation before launching work (best-effort)
HystrixThreadPoolMetrics m = HystrixThreadPoolMetrics.getInstance(
        HystrixThreadPoolKey.Factory.asKey("orders"), null, null);
// simpler: rely on Hystrix itself - implement getFallback() so rejection degrades gracefully

Try / catch

try {
    String r = new MyCommand(key).queue().get(2, TimeUnit.SECONDS);
} catch (ExecutionException e) {
    if (e.getCause() instanceof HystrixRuntimeException
            && ((HystrixRuntimeException) e.getCause()).getFailureType() == HystrixRuntimeException.FailureType.REJECTED) {
        return degradedValue(); // thread pool rejected - back off
    }
    throw e;
}

Prevention

When it happens

Trigger: Scheduling a semaphore- or thread-isolated command's asynchronous work (queue(), observe(), toObservable() subscription) when the pool's underlying queue size >= queueSizeRejectionThreshold; bursty traffic with a small maxQueueSize or low rejection threshold.

Common situations: Thread pool saturated under load spikes: maxQueueSize=-1 (SynchronousQueue, no buffering) or default queueSizeRejectionThreshold=5 with fast producers; commands with long run() times backing up the pool; bulkheading configured too small for the request rate.

Related errors


AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14). Data as JSON: /api/errors/1b6917f353f3603c. Report an issue: GitHub.