pentaho/pentaho-kettle · error · KettlePluginException
The attributes 'plugin_id' and 'driver_class' can't be both…
Error message
The attributes 'plugin_id' and 'driver_class' can't be both empty
What it means
loadDatabaseMetaFromDatabaseElement() reconstructs a DatabaseMeta from a stored element. It needs at least one of the plugin_id (DB_ATTR_ID_PLUGIN_ID) or driver_class attributes to identify which database plugin to instantiate. If both are empty it throws KettlePluginException because the plugin cannot be determined.
Solutions
- Add a valid plugin_id attribute (e.g. 'MySQL', 'POSTGRESQL') to the stored element
- Set the driver_class attribute (e.g. 'com.mysql.cj.jdbc.Driver') so pluginId can be derived via the registry
- Re-save the connection from the UI/SDK so all required attributes are written
Example fix
// before element without DB_ATTR_ID_PLUGIN_ID or DB_ATTR_DRIVER_CLASS // after element.addChild( metaStore.newAttribute( MetaStoreConst.DB_ATTR_ID_PLUGIN_ID, "POSTGRESQL" ) );
Defensive patterns
Strategy: validation
Validate before calling
String pluginId = DatabaseMetaStoreUtil.getChildString( element, MetaStoreConst.DB_ATTR_ID_PLUGIN_ID );
String driver = DatabaseMetaStoreUtil.getChildString( element, MetaStoreConst.DB_ATTR_DRIVER_CLASS );
if ( ( pluginId == null || pluginId.isEmpty() ) && ( driver == null || driver.isEmpty() ) ) {
throw new IllegalStateException( "Element needs plugin_id or driver_class" );
} Prevention
- Always write plugin_id when creating elements programmatically
- Audit metastore elements for required attributes
- Keep driver_class populated even when plugin_id is present
When it happens
Trigger: Loading a stored database element that was written without the plugin_id attribute and without a driver_class attribute.
Common situations: Metastore element created by hand or by a third-party tool; attributes dropped during migration; older export format missing these fields.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- The 'plugin_id' attribute could not be determined using…
- Unable to load database from element with name
- Can not create element type with id…
- Can not create element type with id
- Can't delete element type with name
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/2b67fd4ddfbbdee6.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/metastore/DatabaseMetaStoreUtil.java:193
try {
element.addChild( metaStore.newAttribute( MetaStoreConst.DB_ATTR_JDBC_URL, databaseMeta.getURL() ) );
} catch ( Exception e ) {
throw new MetaStoreException( "Unable to assemble URL from database '" + databaseMeta.getName() + "'", e );
}
return element;
}
public static DatabaseMeta loadDatabaseMetaFromDatabaseElement( IMetaStore metaStore, IMetaStoreElement element ) throws KettlePluginException {
DatabaseMeta databaseMeta = new DatabaseMeta();
PluginRegistry pluginRegistry = PluginRegistry.getInstance();
// Load the appropriate database plugin (database interface)
//
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 pluginView on GitHub (pinned to f3058517a1)