Netflix/Hystrix · warning · RuntimeException
Interrupted while waiting for thread-pools to terminate. Poo
Error message
Interrupted while waiting for thread-pools to terminate. Pools may not be correctly shutdown or cleared.
What it means
HystrixThreadPool.shutdown(timeout, unit) stops every pool and awaits termination; if a waiting thread is interrupted during awaitTermination, it throws RuntimeException('Interrupted while waiting for thread-pools to terminate. Pools may not be correctly shutdown or cleared.') and the static threadPools map is left uncleared.
Source
Thrown at hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPool.java:151
}
/**
* Initiate the shutdown of all {@link HystrixThreadPool} instances and wait up to the given time on each pool to complete.
* <p>
* NOTE: This is NOT thread-safe if HystrixCommands are concurrently being executed
* and causing thread-pools to initialize while also trying to shutdown.
* </p>
*/
/* package */static synchronized void shutdown(long timeout, TimeUnit unit) {
for (HystrixThreadPool pool : threadPools.values()) {
pool.getExecutor().shutdown();
}
for (HystrixThreadPool pool : threadPools.values()) {
try {
while (! pool.getExecutor().awaitTermination(timeout, unit)) {
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while waiting for thread-pools to terminate. Pools may not be correctly shutdown or cleared.", e);
}
}
threadPools.clear();
}
}
/**
* @ExcludeFromJavadoc
* @ThreadSafe
*/
/* package */static class HystrixThreadPoolDefault implements HystrixThreadPool {
private static final Logger logger = LoggerFactory.getLogger(HystrixThreadPoolDefault.class);
private final HystrixThreadPoolProperties properties;
private final BlockingQueue<Runnable> queue;
private final ThreadPoolExecutor threadPool;
private final HystrixThreadPoolMetrics metrics;
private final int queueSize;View on GitHub (pinned to 5ce3bc58c3)
Solutions
- Restore the interrupt and retry shutdown: catch the RuntimeException, call Thread.currentThread().interrupt() is already-signal; re-invoke Hystrix.shutdown() with a longer/second attempt
- Perform shutdown from a dedicated, non-interruptible cleanup path (e.g. contextDestroyed without container-imposed timeouts)
- Increase the timeout passed to shutdown so awaitTermination finishes before any container deadline
- Accept pooled-thread leakage at JVM exit (harmless when the process ends anyway) — only fix if the container keeps running
Example fix
// before
Runtime.getRuntime().addShutdownHook(new Thread(() -> Hystrix.shutdown()));
// after
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try { Hystrix.reset(5, TimeUnit.SECONDS); }
catch (RuntimeException e) { Thread.currentThread().interrupt(); /* JVM exiting */ }
})); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
catch (RuntimeException e) { if (e.getMessage().startsWith("Interrupted while waiting for thread-pools")) { Thread.currentThread().interrupt(); /* optional: retry Hystrix.reset once with a longer timeout */ } } Prevention
- Call Hystrix.reset()/shutdown() from a dedicated cleanup thread with adequate timeout
- Drain in-flight commands before shutdown
- Never rely on interrupt-driven container timeouts for Hystrix teardown
When it happens
Trigger: Calling Hystrix.shutdown() / HystrixThreadPool.shutdown() and having the calling thread receive an interrupt (shutdown hook racing JVM exit, another thread interrupting, container thread interruption during redeploy).
Common situations: Application shutdown hooks where Hystrix shutdown races with JVM teardown; servlet container hot redeploys interrupting cleanup threads; tests that time out and interrupt the thread running Hystrix shutdown.
Related errors
- Not an event that can be converted to HystrixEventType.Threa
- Trying to start null batch which means it was shutdown alrea
- Failed to set Thread Pool properties. {}
- HystrixCommandGroup can not be NULL
- " + getLogMessagePrefix() + " command executed multiple time
AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14).
Data as JSON: /api/errors/d600dbe2bdd5ff47.
Report an issue: GitHub.