pentaho/pentaho-kettle · error · KettlePluginException

The 'plugin_id' attribute could not be determined using…

Error message

The 'plugin_id' attribute could not be determined using 'driver_class' value '${driverClassName}'

What it means

If plugin_id is empty, the loader tries to infer it by matching the stored driver_class against every registered database plugin's getDriverClass(). When no plugin matches, pluginId remains empty and this KettlePluginException is thrown naming the driver class that could not be mapped.

Solutions

  1. Correct the driver_class attribute to the exact class name of a registered database plugin
  2. Set plugin_id directly so no inference is needed
  3. Install/register a database plugin that supports that driver class

Example fix

// before
<attr id="DRIVER_CLASS">com.mysql.jdbc.Driver</attr> // no plugin matches
// after
<attr id="DRIVER_CLASS">com.mysql.cj.jdbc.Driver</attr>
<attr id="PLUGIN_ID">MySQL</attr>
Defensive patterns

Strategy: validation

Validate before calling

PluginRegistry registry = PluginRegistry.getInstance();
boolean matched = registry.getPlugins( DatabasePluginType.class ).stream()
  .anyMatch( p -> driverClassName.equalsIgnoreCase(
    registry.getDatabase( p ).getDriverClass() ) );
if ( !matched && pluginId.isEmpty() ) throw new IllegalStateException( "No plugin for driver " + driverClassName );

Prevention

When it happens

Trigger: Loading an element whose driver_class attribute does not equal any registered database plugin's driver class (pluginId still empty after the registry loop).

Common situations: Driver string from a different vendor/version (e.g. old 'com.mysql.jdbc.Driver' vs new 'com.mysql.cj.jdbc.Driver'); third-party JDBC driver with no corresponding Kettle database plugin; typo in the stored driver class.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/ce7c3fff89c2ddb6. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/metastore/DatabaseMetaStoreUtil.java:207

    //
    String pluginId = getChildString( element, MetaStoreConst.DB_ATTR_ID_PLUGIN_ID );
    String driverClassName = getChildString( element, MetaStoreConst.DB_ATTR_DRIVER_CLASS );
    if ( Utils.isEmpty( pluginId ) && Utils.isEmpty( driverClassName ) ) {
      throw new KettlePluginException( "The attributes 'plugin_id' and 'driver_class' can't be both empty" );
    }
    if ( Utils.isEmpty( pluginId ) ) {
      // Determine pluginId using the plugin registry.
      //
      List<PluginInterface> plugins = pluginRegistry.getPlugins( DatabasePluginType.class );
      for ( PluginInterface plugin : plugins ) {
        DatabaseInterface databaseInterface = (DatabaseInterface) pluginRegistry.loadClass( plugin );
        if ( driverClassName.equalsIgnoreCase( databaseInterface.getDriverClass() ) ) {
          pluginId = plugin.getIds()[0];
        }
      }
    }
    if ( Utils.isEmpty( pluginId ) ) {
      throw new KettlePluginException(
        "The 'plugin_id' attribute could not be determined using 'driver_class' value '" + driverClassName + "'" );
    }

    // Look for the plugin
    //
    PluginInterface plugin = PluginRegistry.getInstance().getPlugin( DatabasePluginType.class, pluginId );
    DatabaseInterface databaseInterface = (DatabaseInterface) PluginRegistry.getInstance().loadClass( plugin );
    databaseInterface.setPluginId( pluginId );
    databaseMeta.setDatabaseInterface( databaseInterface );

    databaseMeta.setObjectId( new StringObjectId( element.getId() ) );
    databaseMeta.setName( element.getName() );
    databaseMeta.setDescription( getChildString( element, MetaStoreConst.DB_ATTR_ID_DESCRIPTION ) );

    String accessTypeString = getChildString( element, MetaStoreConst.DB_ATTR_ID_ACCESS_TYPE );
    if ( Utils.isEmpty( accessTypeString ) ) {
      accessTypeString = DatabaseMeta.getAccessTypeDesc( DatabaseMeta.TYPE_ACCESS_NATIVE );
    }

View on GitHub (pinned to f3058517a1)