apache/shardingsphere · warning · SQLWrapperException
5
5
Error message
Underlying SQL state: %s, underlying error code: %s.
What it means
Thrown as SQLWrapperException when closing a group of DataSources and one or more close() calls fail with SQLException. The wrapper chains every underlying failure via SQLException.setNextException, and its message template reports the underlying SQL state and error code so callers can see which driver/database actually failed. It is a shutdown-time aggregation error: the original causes are preserved in the chain, not swallowed.
Source
Thrown at infra/util/src/main/java/org/apache/shardingsphere/infra/util/close/DataSourcesCloser.java:63
((AutoCloseable) each).close();
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:ON
causes.add(ex);
}
}
}
if (!causes.isEmpty()) {
throwException(causes);
}
}
private static void throwException(final Collection<Exception> causes) {
SQLException sqlException = new SQLException("");
for (Exception each : causes) {
sqlException.setNextException(new SQLException(each));
}
throw new SQLWrapperException(sqlException);
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Inspect the wrapped exception chain via getNextException() on the SQLWrapperException to find the real SQLState/vendor code of the failing datasource.
- Ensure connections/statements are closed by application code before container shutdown invokes datasource close.
- If the error is transient (DB restarted), verify the database is reachable and retry the shutdown/close sequence.
- If a specific datasource is misconfigured (wrong URL, expired credentials), fix its configuration so close() no longer fails.
Example fix
// before
catch (final SQLException ex) {
throw new SQLWrapperException(sqlException);
}
// caller: inspect chain
// after
catch (final SQLWrapperException ex) {
SQLException next = ex.getNextException();
while (next != null) {
LOG.error("close failed: state={}, code={}", next.getSQLState(), next.getErrorCode(), next);
next = next.getNextException();
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// before teardown: verify pools are idle
for (DataSource ds : pools) { /* drain/quiet app queries first */ } Try / catch
catch (final SQLWrapperException ex) { for (SQLException n = ex.getNextException(); n != null; n = n.getNextException()) { log("state={} code={}", n.getSQLState(), n.getErrorCode()); } } Prevention
- Close all application connections before datasource close
- Never close datasources twice
- Log the full exception chain to identify the failing pool
When it happens
Trigger: Calling DataSourcesCloser.close (or any path that closes multiple pooled DataSources, e.g. datasource teardown on application shutdown) where at least one underlying JDBC DataSource.close() throws a SQLException; the collected causes are wrapped and rethrown.
Common situations: Application shutdown while connections are still in flight; connection pools (HikariCP/DBCP) already invalidated or their DB unreachable at close time; closing a datasource that failed mid-initialization; double-closing datasources in a context-destroy callback.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/5da38285cf119516.
Report an issue: GitHub.