{"record":{"id":"b8f5764ae1fec246","repo":"brettwooldridge/HikariCP","slug":"wrapped-connection-is-not-an-instance-of-iface","errorCode":null,"errorMessage":"Wrapped connection is not an instance of ${iface}","messagePattern":"Wrapped connection is not an instance of (.+?)","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java","lineNumber":531,"sourceCode":"   @Override\n   public final boolean isWrapperFor(Class<?> iface) throws SQLException\n   {\n      return iface.isInstance(delegate) || (delegate != null && delegate.isWrapperFor(iface));\n   }\n\n   /** {@inheritDoc} */\n   @Override\n   @SuppressWarnings(\"unchecked\")\n   public final <T> T unwrap(Class<T> iface) throws SQLException\n   {\n      if (iface.isInstance(delegate)) {\n         return (T) delegate;\n      }\n      else if (delegate != null) {\n          return delegate.unwrap(iface);\n      }\n\n      throw new SQLException(\"Wrapped connection is not an instance of \" + iface);\n   }\n\n   // **********************************************************************\n   //                         Private classes\n   // **********************************************************************\n\n   private static final class ClosedConnection\n   {\n      static final Connection CLOSED_CONNECTION = getClosedConnection();\n\n      private static Connection getClosedConnection()\n      {\n         InvocationHandler handler = (proxy, method, args) -> {\n            final String methodName = method.getName();\n            switch (methodName) {\n               case \"isClosed\":\n                  return Boolean.TRUE;\n               case \"isValid\":","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/brettwooldridge/HikariCP/blob/a4d93f4f85517f90e632b795486d7102e933d7ff/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java#L513-L549","documentation":"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.","triggerScenarios":"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.","commonSituations":"Vendor-specific feature access (arrays, notifications, statement caching) through HikariCP proxies; mocking connections in tests; wrapping HikariCP inside another pool.","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"],"exampleFix":"// before\nPGConnection pg = conn.unwrap(PGConnection.class); // may throw\n\n// after\nif (conn.isWrapperFor(PGConnection.class)) {\n   PGConnection pg = conn.unwrap(PGConnection.class);\n   pg.addNotificationListener(...);\n}","handlingStrategy":"type-guard","validationCode":"if (conn.isWrapperFor(VendorConnection.class)) { ... }","typeGuard":"boolean canUnwrapConn(Connection c, Class<?> iface) {\n    try { return c != null && !c.isClosed() && c.isWrapperFor(iface); }\n    catch (SQLException e) { return false; }\n}","tryCatchPattern":"try { v = conn.unwrap(iface); }\ncatch (SQLException e) {\n    if (e.getMessage().contains(\"not an instance of\")) { /* fall back to standard API */ }\n    else throw e;\n}","preventionTips":["Guard every unwrap with isWrapperFor","Unwrap to driver-documented interfaces","Avoid unwrap on possibly-closed connections"],"tags":["hikaricp","jdbc","unwrap","proxy-connection"],"backgroundTag":null,"analyzedSha":"a4d93f4f85517f90e632b795486d7102e933d7ff","analyzedAt":"2026-08-14T12:11:37.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}