pentaho/pentaho-kettle · error · KettleDatabaseException
Unable to register delegating driver for class
Error message
Unable to register delegating driver for class {driverClassCanonicalName} What it means
Thrown by Database.registerDelegatingDriver when instantiating a JDBC driver class and registering a DelegatingDriver wrapper with DriverManager fails. Any of ClassNotFoundException-driven instantiation problems ( reflective construction ) or SQLException during registration results in this KettleDatabaseException. The class was found but could not be turned into a live registered driver.
Solutions
- Verify the configured driver class has a public no-arg constructor and implements java.sql.Driver
- Check the full cause chain (InstantiationException/NoSuchMethodException/SQLException) to identify the exact failure
- Ensure the driver JAR matches the driver class name/version expected by the database plugin
- Remove duplicate or stale driver JARs from the plugin's lib directory
- Check that no SecurityManager/classloader policy blocks reflective instantiation
Example fix
// before (broken driver class)
Class.forName("com.broken.Driver") // compiles, but no public no-arg ctor
// after
// use the vendor's documented driver class, e.g.
String cls = "org.postgresql.Driver"; // has public no-arg ctor and implements java.sql.Driver Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(driverClassName, true, loader); if (!java.sql.Driver.class.isAssignableFrom(c)) throw new IllegalStateException(driverClassName + " is not a java.sql.Driver"); c.getDeclaredConstructor().setAccessible(true); // throws NoSuchMethodException early if missing
Type guard
boolean isValidDriverClass(Class<?> c) { return c != null && java.sql.Driver.class.isAssignableFrom(c); } Try / catch
try { db.connect(); } catch (KettleDatabaseException e) { if (e.getMessage().startsWith("Unable to register delegating driver")) { log.error("Driver JAR/class invalid: " + e.getCause(), e); } else throw e; } Prevention
- Always ship official vendor driver JARs
- Verify driver classes implement java.sql.Driver before configuring plugins
- Keep only one version of each driver JAR in the plugin lib folder
- Read the root cause chain, not just the wrapper message
When it happens
Trigger: loadStaticDriver calls registerDelegatingDriver for a plugin's driver class; the driver class has no no-arg constructor, the constructor throws, the class is abstract/interface, access is denied, or DriverManager.registerDriver throws SQLException (e.g. driver already registered incompatibly).
Common situations: Driver JAR present but class is not a valid java.sql.Driver; driver class loaded by the wrong classloader so newInstance fails; duplicate plugin registrations racing; a broken/incompatible driver version in the plugin folder.
Related errors
- An error occurred executing SQL:
- An error occurred executing SQL:
- Couldn't execute SQL:
- Couldn't find any rows because of an error :
- Couldn't get a result because of an error :
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/6791e1696f9cbc08.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:670
}
} catch ( NoClassDefFoundError | ClassNotFoundException e ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG,
"Database.Exception.UnableToFindClassMissingDriver", classname, plugin.getName() ), e );
} catch ( Exception e ) {
throw new KettleDatabaseException( "Exception while loading class", e );
}
}
private void registerDelegatingDriver( Class<?> driverClass ) throws KettleDatabaseException {
String pluginId =
PluginRegistry.getInstance().getPluginId( DatabasePluginType.class, databaseMeta.getDatabaseInterface() );
Set<String> registeredDriversFromPlugin = registeredDrivers.computeIfAbsent( pluginId, k -> new HashSet<>() );
// Prevent registering multiple delegating drivers for same class, plugin
if ( !registeredDriversFromPlugin.contains( driverClass.getCanonicalName() ) ) {
try {
DriverManager.registerDriver( new DelegatingDriver( (Driver) driverClass.getDeclaredConstructor().newInstance() ) );
} catch ( InstantiationException | IllegalAccessException | NoSuchMethodException | java.lang.reflect.InvocationTargetException | SQLException e ) {
throw new KettleDatabaseException(
"Unable to register delegating driver for class " + driverClass.getCanonicalName(), e );
}
registeredDriversFromPlugin.add( driverClass.getCanonicalName() );
}
}
private String resolveUrl( String partitionId ) throws KettleDatabaseException {
if ( databaseMeta.isPartitioned() && !Utils.isEmpty( partitionId ) ) {
return environmentSubstitute( databaseMeta.getURL( partitionId ) );
}
return environmentSubstitute( databaseMeta.getURL() );
}
private String[] resolveCredentials( String partitionId ) {
if ( databaseMeta.isPartitioned() && !Utils.isEmpty( partitionId ) ) {
PartitionDatabaseMeta partition = databaseMeta.getPartitionMeta( partitionId );
if ( partition != null && !Utils.isEmpty( partition.getUsername() ) ) {
return new String[] { partition.getUsername(),View on GitHub (pinned to f3058517a1)