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

  1. Verify the configured driver class has a public no-arg constructor and implements java.sql.Driver
  2. Check the full cause chain (InstantiationException/NoSuchMethodException/SQLException) to identify the exact failure
  3. Ensure the driver JAR matches the driver class name/version expected by the database plugin
  4. Remove duplicate or stale driver JARs from the plugin's lib directory
  5. 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

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


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)