apache/druid · error · IllegalStateException

interrupted

Error message

interrupted

What it means

ReadableInputStreamFrameChannel reads frames from an InputStream on a background thread. If the reading thread is interrupted while blocking on the input stream, the channel quietly closes the stream and throws ISE wrapping the InterruptedException with the thread name plus 'interrupted'. It signals that blocking I/O was cancelled mid-read.

Solutions

  1. Check whether the interruption was an intentional cancellation (query killed/shutdown); if so, treat it as expected and propagate/ignore.
  2. If not intentional, audit thread-pool configuration and code paths that call Future.cancel(true) or Thread.interrupt().
  3. Ensure the channel is closed in a finally block so resources are released after the ISE.
  4. Retry the transfer on a fresh channel if the interrupt was spurious.

Example fix

// before
RowsAndColumns rac = channel.read(); // ISE ...interrupted on cancel
// after
try {
  RowsAndColumns rac = channel.read();
} catch (IllegalStateException e) {
  if (e.getCause() instanceof InterruptedException && cancellationToken.isCancelled()) {
    return; // expected cancellation
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (Thread.currentThread().isInterrupted()) { /* resolve interruption before starting reads */ }

Try / catch

try { channel.read(); } catch (IllegalStateException e) { if (e.getCause() instanceof InterruptedException) { /* handle cancellation or restore interrupt: Thread.currentThread().interrupt(); */ } else throw e; }

Prevention

When it happens

Trigger: Calling startReading() (triggered via isFinished, canRead, read, or readabilityFuture) and the worker thread is interrupted while waiting for bytes on the underlying InputStream — e.g. during query cancellation or executor shutdown.

Common situations: Query cancellation in the MSQ/clustered engine interrupts task threads; shutting down a Druid service while a frame transfer is in flight; misconfigured thread pools that interrupt idle workers.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/7bddd10c51bed878. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/frame/channel/ReadableInputStreamFrameChannel.java:191

      while (true) {
        if (!keepReading) {
          try {
            synchronized (readMonitor) {
              if (!keepReading) {
                readMonitor.wait(nextRetrySleepMillis(nTry));
              }
            }
            synchronized (lock) {
              if (inputStreamFinished || inputStreamError || delegate.isErrorOrFinished()) {
                return;
              }
            }
            ++nTry;
          }
          catch (InterruptedException e) {
            // close input stream anyway if the thread interrupts
            IOUtils.closeQuietly(inputStream);
            throw new ISE(e, Thread.currentThread().getName() + "interrupted");
          }

        } else {
          synchronized (lock) {
            nTry = 1; // Reset the value of try because we are not waiting on the data from the inputStream
            // if done reading method is called we should not read input stream further
            if (inputStreamFinished) {
              delegate.doneWriting();
              break;
            }
            try {

              int bytesRead = inputStream.read(buffer);
              if (bytesRead == -1) {
                inputStreamFinished = true;
                delegate.doneWriting();
                // eagerly release input stream resources since everything is read.
                IOUtils.closeQuietly(inputStream);

View on GitHub (pinned to 9b90983fd2)