apache/cassandra · error · IllegalStateException

HintsService has already been shut down

Error message

HintsService has already been shut down

What it means

Fired in HintsService.shutdownBlocking when isShutDown is already true: shutdown is requested a second time. The service is idempotent-guarded — instead of double-shutting down executors, it throws IllegalStateException('HintsService has already been shut down') to signal misuse of the lifecycle API.

Source

Thrown at src/java/org/apache/cassandra/hints/HintsService.java:325

        for (HintsStore store : catalog.storesCollection())
        {
            if (store == null)
                continue;
            size += store.getTotalFileSize();
        }
        return size;
    }

    /**
     * Gracefully and blockingly shut down the service.
     *
     * Will abort dispatch sessions that are currently in progress (which is okay, it's idempotent),
     * and make sure the buffers are flushed, hints files written and fsynced.
     */
    public synchronized void shutdownBlocking() throws ExecutionException, InterruptedException
    {
        if (isShutDown)
            throw new IllegalStateException("HintsService has already been shut down");
        isShutDown = true;

        if (triggerDispatchFuture != null)
            triggerDispatchFuture.cancel(false);
        pauseDispatch();

        triggerFlushingFuture.cancel(false);

        triggerCleanupFuture.cancel(false);

        writeExecutor.flushBufferPool(bufferPool).get();
        writeExecutor.closeAllWriters().get();

        dispatchExecutor.shutdownBlocking();
        writeExecutor.shutdownBlocking();

        HintsServiceDiagnostics.dispatchingShutdown(this);
        bufferPool.close();

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Track shutdown with your own flag or check isShutDown state before calling again
  2. Catch IllegalStateException and ignore — the service is already stopped, which is the desired end state
  3. Consolidate shutdown paths so only one component calls shutdownBatchlogAndHints
  4. In tests, use the framework's cluster close() rather than manual shutdown

Example fix

// before
HintsService.instance.shutdownBlocking();
// after
try {
    HintsService.instance.shutdownBlocking();
} catch (IllegalStateException e) {
    // already shut down — nothing to do
}
Defensive patterns

Strategy: try-catch

Validate before calling

// only call once per node lifecycle; track locally
private final AtomicBoolean hintsShutdownDone = new AtomicBoolean(false);
if (!hintsShutdownDone.compareAndSet(false, true)) return;

Try / catch

try {
    HintsService.instance.shutdownBlocking();
} catch (IllegalStateException e) {
    // already shut down; safe to ignore
}

Prevention

When it happens

Trigger: Calling HintsService.shutdownBlocking() twice — e.g. shutdown hooks and StorageService shutdown both invoking it, or test code shutting down the service and then the node also doing so.

Common situations: Double shutdown via both JVM shutdown hook and explicit stop; batchlog-and-hints shutdown invoked after a prior manual shutdown in embedded/test setups.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/7842275d89f97264. Report an issue: GitHub.