apache/seatunnel · warning
Python source thread did not finish within ms while…
Error message
Python source {} thread did not finish within {}ms while closing; it may keep running along with any descendant process it holds open What it means
During close(), the Python source reader joins its worker thread with a bounded timeout. If the thread does not finish in time and no earlier close failure was recorded, it logs this warning instead of failing the close — because the leaked thread (and any child process it keeps alive) would otherwise be invisible.
Solutions
- Make the Python script respond to EOF/cancellation promptly (close streams, handle SIGTERM)
- Increase the close timeout so legitimate slow shutdowns complete
- Check the running script for child processes it spawns that keep handles open
- If the warning recurs, terminate the leaked process at the OS level (kill the resolved executable pid)
Defensive patterns
Strategy: fallback
Validate before calling
// ensure the script exits promptly on EOF final String scriptCheck = "import sys; sys.stdin.readline(); sys.exit(0)"; // verify behaves so under timeout
Try / catch
try { reader.close(); } catch (IOException e) { /* closeException from join timeout */ log.warn("python reader close incomplete: {}", e.getMessage()); } Prevention
- Write scripts that exit on stdin EOF and SIGTERM
- Avoid spawning detached children from the Python process
- Size the close timeout to expected script shutdown time
- Monitor for leaked python processes in task managers
When it happens
Trigger: joinThread is called from close(); streamCloser/reader thread does not terminate within timeoutMillis; failOnTimeout=false or an earlier join already produced closeException, so it is logged rather than thrown.
Common situations: Python script blocked on reading stdin or a long computation that ignores cancellation; descendant processes inherited from the Python process keeping the pipe open; very short close timeouts.
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
- Kudu client executor did not terminate after forced…
- Python source process did not terminate after forced…
- Python source stream closer did not finish within
- ANTHROPIC_API_KEY environment variable is required for…
- anthropic package required for AI_PROVIDER=anthropic…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/005d03986ccbde71.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java:712
if (closeRequested) {
thread.interrupt();
}
try {
thread.join(timeoutMillis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
if (closeException == null) {
return new IOException("Interrupted while closing python source " + threadName, e);
}
}
if (thread.isAlive()) {
if (failOnTimeout && closeException == null) {
return new IOException("Timed out while closing python source " + threadName);
}
// Not surfaced as a close failure (failOnTimeout=false, or an earlier join already
// produced closeException), but the thread outliving its bounded join is otherwise
// invisible: log it so a leaked thread or inherited descendant is observable.
LOG.warn(
"Python source {} thread did not finish within {}ms while closing; it may keep"
+ " running along with any descendant process it holds open",
threadName,
timeoutMillis);
}
return closeException;
}
private synchronized void appendStderrLine(String line) {
if (recentStderrLines.size() == STDERR_HISTORY_LIMIT) {
recentStderrLines.removeFirst();
}
recentStderrLines.addLast(line);
}
private synchronized String formatRecentStderr() {
if (recentStderrLines.isEmpty()) {
return "";View on GitHub (pinned to cf67b549a7)