brettwooldridge/HikariCP · error · SQLException
Wrapped connection is not an instance of ${iface}
Error message
Wrapped connection is not an instance of ${iface} What it means
ProxyConnection.unwrap(iface) throws SQLException unless the wrapped (delegate) Connection is an instance of the requested interface or can itself unwrap it. HikariCP returns proxies for pooled connections, so vendor-specific unwrapping only works if the real driver connection lies underneath and supports the type.
Source
Thrown at src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java:531
@Override
public final boolean isWrapperFor(Class<?> iface) throws SQLException
{
return iface.isInstance(delegate) || (delegate != null && delegate.isWrapperFor(iface));
}
/** {@inheritDoc} */
@Override
@SuppressWarnings("unchecked")
public final <T> T unwrap(Class<T> iface) throws SQLException
{
if (iface.isInstance(delegate)) {
return (T) delegate;
}
else if (delegate != null) {
return delegate.unwrap(iface);
}
throw new SQLException("Wrapped connection is not an instance of " + iface);
}
// **********************************************************************
// Private classes
// **********************************************************************
private static final class ClosedConnection
{
static final Connection CLOSED_CONNECTION = getClosedConnection();
private static Connection getClosedConnection()
{
InvocationHandler handler = (proxy, method, args) -> {
final String methodName = method.getName();
switch (methodName) {
case "isClosed":
return Boolean.TRUE;
case "isValid":View on GitHub (pinned to a4d93f4f85)
Solutions
- Guard with conn.isWrapperFor(iface) before unwrap
- Access vendor APIs by unwrapping to the exact interface the driver documents (e.g. org.postgresql.PGConnection)
- If a custom DataSource wraps the real one, ensure its connections implement unwrap correctly
- Keep a parallel vendor-specific handle instead of unwrapping when the type is not exposed
Example fix
// before
PGConnection pg = conn.unwrap(PGConnection.class); // may throw
// after
if (conn.isWrapperFor(PGConnection.class)) {
PGConnection pg = conn.unwrap(PGConnection.class);
pg.addNotificationListener(...);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (conn.isWrapperFor(VendorConnection.class)) { ... } Type guard
boolean canUnwrapConn(Connection c, Class<?> iface) {
try { return c != null && !c.isClosed() && c.isWrapperFor(iface); }
catch (SQLException e) { return false; }
} Try / catch
try { v = conn.unwrap(iface); }
catch (SQLException e) {
if (e.getMessage().contains("not an instance of")) { /* fall back to standard API */ }
else throw e;
} Prevention
- Guard every unwrap with isWrapperFor
- Unwrap to driver-documented interfaces
- Avoid unwrap on possibly-closed connections
When it happens
Trigger: conn.unwrap(OracleConnection.class) when the delegate is a PG/MySQL connection or another wrapper that cannot unwrap; unwrap to a class the driver does not implement; unwrap to a non-Connection interface.
Common situations: Vendor-specific feature access (arrays, notifications, statement caching) through HikariCP proxies; mocking connections in tests; wrapping HikariCP inside another pool.
Related errors
- Wrapped DataSource is not an instance of ${iface}
- Wrapped DatabaseMetaData is not an instance of {}
- Wrapped ResultSet is not an instance of {}
- Wrapped statement is not an instance of {}
- DataSource returned null unexpectedly
AI-assisted analysis of brettwooldridge/HikariCP@a4d93f4f85 (2026-08-14).
Data as JSON: /api/errors/b8f5764ae1fec246.
Report an issue: GitHub.