apache/seatunnel · warning
Error sink worker thread is still alive after close…
Error message
Error sink worker thread is still alive after close timeout. jobId={}, pluginName={}, threadName={}. Will release the error sink classloader anyway to reduce classloader leak risk. What it means
DefaultErrorSinkWriter.close() waits DEFAULT_CLOSE_TIMEOUT_MILLIS for the error-sink worker thread to finish. If the thread is still alive after the timeout, this warning is logged and the error-sink classloader is released anyway to avoid leaking it. It indicates the error sink could not finish draining within the close timeout, so data may have been dropped.
Solutions
- Check the error sink (pluginName in the log) for slowness or blocked connections and increase its write throughput or batch size.
- Ensure the job is cancelled gracefully so the drain loop can finish before close.
- Check for stuck network/DB connections from the sink and tune its timeout options.
- If leaks persist, verify plugin classloader cleanup and report/inspect DefaultErrorSinkWriter timeout behavior for your SeaTunnel version.
Example fix
// before: no graceful drain, worker blocked on slow sink sinkWriter.write(record); // blocking JDBC call with no timeout // after: bound the write so close() can finish in time statement.setQueryTimeout(10); sinkWriter.write(record);
Defensive patterns
Strategy: fallback
Try / catch
// close() already swallows; monitor logs
try {
errorSinkWriter.close();
} catch (Throwable t) {
log.error("error sink close failed after timeout", t);
} Prevention
- Keep the error sink fast (timeouts on JDBC statements, batch tuning).
- Cancel/stop jobs gracefully rather than hard-kill so the drain loop drains.
- Watch logs for this warning as an indicator of slow error sinks.
- Size the close timeout for your sink's worst-case latency.
When it happens
Trigger: close() is called while the drain loop still has queued error records and the sink writer (e.g. a slow JDBC/error sink) does not terminate within the close timeout, leaving currentWorkerThread alive.
Common situations: Error sink writing to a slow/unresponsive database or network sink during job shutdown; a sink writer blocked in I/O (e.g. MySQL connection stuck); excessive queued error rows at cancel/stop time.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Error sink is closing for stage
- Failed to close error sink writer
- Failed to invoke . ()
- Both channel and connection closing failed. Logging channel…
- close event processor error
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/919eb0658e1976f5.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/DefaultErrorSinkWriter.java:271
throw new RuntimeException(e);
}
}
throwWorkerFailureIfAny();
}
@Override
public void close() throws Exception {
closed = true;
Thread currentWorkerThread = workerThread;
if (currentWorkerThread != null) {
currentWorkerThread.interrupt();
}
waitForWorkerTermination(DEFAULT_CLOSE_TIMEOUT_MILLIS);
Throwable closeEx = null;
try {
if (currentWorkerThread != null && currentWorkerThread.isAlive()) {
log.warn(
"Error sink worker thread is still alive after close timeout. jobId={}, pluginName={}, threadName={}. "
+ "Will release the error sink classloader anyway to reduce classloader leak risk.",
jobId,
sinkConfig.getPluginName(),
currentWorkerThread.getName());
closeEx =
new RuntimeException(
String.format(
"Timed out waiting for error sink worker to close. jobId=%d, pluginName=%s",
jobId, sinkConfig.getPluginName()));
} else {
// Worker thread stopped; close remaining resources.
closeWriterIfPossible();
}
} catch (Throwable e) {
closeEx = e;
log.warn("Failed to close error sink writer", e);
} finally {View on GitHub (pinned to cf67b549a7)