apache/seatunnel · error · IOException

Interrupted while draining Python source stdout after proces

Error message

Interrupted while draining Python source stdout after process exit

What it means

After the Python process exits, the reader joins the stdout pump thread with a deadline to drain any buffered output before finishing. If that join is interrupted, the InterruptedException is converted to this IOException so the failure surfaces through the normal source error path, with the interrupt flag restored first.

Source

Thrown at seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java:580

            if (System.nanoTime() >= stdoutCloseDeadlineNanos) {
                throw inheritedStdoutTimeout();
            }
            return false;
        }

        long remainingNanos = stdoutCloseDeadlineNanos - System.nanoTime();
        if (remainingNanos <= 0) {
            throw inheritedStdoutTimeout();
        }
        long waitMillis =
                Math.min(
                        PROCESS_EXIT_CHECK_TIMEOUT_MILLIS,
                        Math.max(1L, TimeUnit.NANOSECONDS.toMillis(remainingNanos)));
        try {
            stdoutPumpThread.join(waitMillis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException(
                    "Interrupted while draining Python source stdout after process exit", e);
        }

        if (closeRequested) {
            return false;
        }
        if (!stdoutLines.isEmpty()) {
            if (System.nanoTime() >= stdoutCloseDeadlineNanos) {
                throw inheritedStdoutTimeout();
            }
            return false;
        }
        if (isAlive(stdoutPumpThread)) {
            if (System.nanoTime() >= stdoutCloseDeadlineNanos) {
                throw inheritedStdoutTimeout();
            }
            return false;
        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. If the job was intentionally stopped, this is expected teardown noise
  2. Rerun the job; buffered data from the child is lost for the interrupted attempt
  3. Avoid long-lived buffered output in the script (flush prints promptly) so drains finish fast
Defensive patterns

Strategy: try-catch

Try / catch

try {
    reader.close();
} catch (IOException e) {
    if (e.getMessage().contains("Interrupted while draining")) {
        // expected during cancellation; restore/check interrupt flag
    }
}

Prevention

When it happens

Trigger: Thread interruption during finishPumpsAfterProcessExit's awaitStdoutPumpAfterProcessExit — i.e. task cancellation, engine shutdown, or job failure arriving while the source is draining the child's remaining stdout.

Common situations: Job cancelled while the Python process just finished; cluster shutdown mid-checkpoint; a stop-with-savepoint triggering interrupts as the source winds down.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/38073aad663df54c. Report an issue: GitHub.