apache/shardingsphere · error · SQLFeatureNotSupportedException
`%s` cannot be unwrapped as `%s`
Error message
`%s` cannot be unwrapped as `%s`
What it means
SQLFeatureNotSupportedException from WrapperAdapter.unwrap(Class<T>) when the requested iface is not an instance of the wrapper object (isWrapperFor returns false). ShardingSphere's JDBC wrappers only unwrap to types they actually implement — the ShardingSphere class hierarchy, not the underlying vendor Connection/Statement classes.
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/WrapperAdapter.java:42
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.sql.Wrapper;
/**
* Adapter for {@code java.sql.Wrapper}.
*/
@Getter
public abstract class WrapperAdapter implements Wrapper {
private final MethodInvocationRecorder<Statement> methodInvocationRecorder = new MethodInvocationRecorder<>();
@SuppressWarnings("unchecked")
@Override
public final <T> T unwrap(final Class<T> iface) throws SQLException {
if (isWrapperFor(iface)) {
return (T) this;
}
throw new SQLFeatureNotSupportedException(String.format("`%s` cannot be unwrapped as `%s`", getClass().getName(), iface.getName()));
}
@Override
public final boolean isWrapperFor(final Class<?> iface) {
return iface.isInstance(this);
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Use unwrap with interfaces the proxy implements (java.sql.Connection, Statement, etc.) — these succeed.
- Fetch the vendor connection through ShardingSphere's own escape hatch (e.g. getRawConnection()/driver-specific API or execute on the physical datasource) instead of unwrap.
- Configure the framework/ORM to disable the vendor-specific feature that triggers the unwrap call.
- Isolate vendor-specific operations on a separate, non-ShardingSphere datasource.
Example fix
// before
MySQLConnection mysql = conn.unwrap(MySQLConnection.class); // throws
// after
// run vendor-specific work on the underlying pool directly
try (Connection raw = hikariDataSource.getConnection()) {
MySQLConnection mysql = raw.unwrap(MySQLConnection.class);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!conn.isWrapperFor(MySQLConnection.class)) { /* vendor API unavailable via proxy */ } Type guard
boolean canUnwrapVendor(Connection c, Class<?> iface) { return c.isWrapperFor(iface); } Try / catch
try { MySQLConnection mc = conn.unwrap(MySQLConnection.class); } catch (SQLFeatureNotSupportedException ex) { fallbackToGenericPath(); } Prevention
- Always call isWrapperFor before unwrap
- Use a separate physical datasource for vendor-specific operations
- Do not assume proxies forward unwrap to the real connection
When it happens
Trigger: Calling unwrap() on a ShardingSphere Connection/Statement/ResultSet with a class the proxy does not implement — most commonly MySQLConnection.class, PGConnection.class, or another driver-specific interface expected by ORM or framework code.
Common situations: Libraries trying to access vendor-specific APIs through the proxy (e.g. MySQL 'useLocalSessionState' tweaks, COPY for Postgres); Hibernate/JOOQ feature detection via unwrap; code assuming the proxy forwards unwrap to the real connection.
Related errors
- `%s` cannot be unwrapped as `%s`
- Unable to unwrap runtime database data source to `%s`.
- Unsupported BLR version: %s
- Expected blr_begin
- Expected blr_message
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/5b4e9d9463c35f5a.
Report an issue: GitHub.