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

  1. Guard with conn.isWrapperFor(iface) before unwrap
  2. Access vendor APIs by unwrapping to the exact interface the driver documents (e.g. org.postgresql.PGConnection)
  3. If a custom DataSource wraps the real one, ensure its connections implement unwrap correctly
  4. 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

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


AI-assisted analysis of brettwooldridge/HikariCP@a4d93f4f85 (2026-08-14). Data as JSON: /api/errors/b8f5764ae1fec246. Report an issue: GitHub.