apache/seatunnel · warning · IOException
Error while closing Databend source reader
Error message
Error while closing Databend source reader
What it means
This error is thrown by DatabendSourceReader.close() when releasing the JDBC Statement or Connection fails with a SQLException during reader shutdown. The original SQLException is wrapped in an IOException so it surfaces as a source-reader close failure rather than a read failure. It usually indicates the connection was already broken or already closed by the time cleanup ran.
Source
Thrown at seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/source/DatabendSourceReader.java:316
typeName);
return BasicType.STRING_TYPE;
}
}
@Override
public void close() throws IOException {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new IOException("Error while closing Databend source reader", e);
}
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Inspect the wrapped SQLException cause: if it reports 'connection already closed' or socket timeout, the close failure is benign and the reader was effectively cleaned up - fix the underlying connection stability instead
- Enable JDBC keepalive/heartbeat and tune Datasense/proxy idle timeouts so connections survive long reads
- Wrap each close() (statement, connection) in its own try-catch so one resource failing to close does not abort the other's cleanup
- Verify network stability between the SeaTunnel worker and Databend (firewalls, NAT idle timeouts, Databend query timeouts)
Example fix
// before
statement.close();
connection.close();
// after
try {
if (statement != null) statement.close();
} catch (SQLException e) {
log.warn("Failed to close Databend statement", e);
}
try {
if (connection != null) connection.close();
} catch (SQLException e) {
log.warn("Failed to close Databend connection", e);
} Defensive patterns
Strategy: try-catch
Validate before calling
// before closing: check connection validity
if (connection != null && !connection.isClosed()) {
connection.close();
} Type guard
boolean isOpen(Connection c) { try { return c != null && !c.isClosed(); } catch (SQLException e) { return false; } } Try / catch
try { reader.close(); } catch (IOException e) {
if (e.getCause() instanceof SQLException && "08003".equals(((SQLException) e.getCause()).getSQLState())) {
log.warn("Connection already closed; ignoring", e);
} else { throw e; }
} Prevention
- Always null-check and isClosed()-check JDBC resources before closing
- Tune TCP/JDBC keepalive so idle connections are not dropped mid-job
- Test reader close paths under job cancellation to ensure cleanup is fault-tolerant
When it happens
Trigger: Calling close() on the reader while the JDBC connection to Databend has been dropped (network cut, Databend restarted, idle timeout) so connection.close() throws; closing an already-closed connection; driver-level socket errors during statement.close().
Common situations: Long-running batch jobs where Databend or a LB closes idle connections; container network interruptions; job cancellation racing with connection teardown; duplicate close() calls on the same reader.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- failed to close arrow stream reader.
- DRIVER_NOT_FOUND
- CONNECT_FAILED
- SQL_OPERATION_FAILED
- CONNECT_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/5662c2f1b165106f.
Report an issue: GitHub.