pentaho/pentaho-kettle · error · KettleDatabaseException

database type with plugin id [] couldn't be found!

Error message

database type with plugin id [] couldn't be found!

What it means

DatabaseMeta.findDatabaseInterface(databaseTypeDesc) looks up a plugin by id then by name in the PluginRegistry and throws KettleDatabaseException if both lookups return null. Unlike getDatabaseInterface (which returns a message-key based error), this throws a literal message naming the unresolved plugin id. The database type is simply not registered in this JVM.

Solutions

  1. Correct the type string to match a registered plugin id or name exactly (id lookup is tried first, then name).
  2. Deploy the referenced database plugin jar to plugins/ and restart the JVM.
  3. After upgrading Pentaho, remap deprecated/renamed plugin ids in stored connection metadata.
  4. Call PluginRegistry.getPlugins(DatabasePluginType.class) first to validate the type exists.

Example fix

// before
DatabaseInterface di = DatabaseMeta.findDatabaseInterface(typeFromXml);
// after
if (DatabaseMeta.findDatabaseInterface(typeFromXml) == null && !isPluginRegistered(typeFromXml)) {
  log.logBasic("Database type " + typeFromXml + " not available, defaulting to GENERIC");
}
DatabaseInterface di = DatabaseMeta.findDatabaseInterface(typeFromXml != null ? typeFromXml : "GENERIC");
Defensive patterns

Strategy: type-guard

Validate before calling

if (type == null || (!idExists(type) && !nameExists(type))) {
  log.warn("Database type unresolved: " + type);
  type = "GENERIC";
}

Type guard

boolean resolvableType(String t) {
  PluginRegistry r = PluginRegistry.getInstance();
  return t != null && (r.getPlugin(DatabasePluginType.class, t) != null
    || r.findPluginWithName(DatabasePluginType.class, t) != null);
}

Try / catch

try {
  DatabaseInterface di = DatabaseMeta.findDatabaseInterface(t);
} catch (KettleDatabaseException e) {
  throw new UnavailableDatabasePluginException(t, e); // domain-specific handling
}

Prevention

When it happens

Trigger: Any code path that calls findDatabaseInterface with an unknown type string — e.g. DatabaseMeta.di (internal type resolution) when loading connections from XML or repositories with unregistered plugin types.

Common situations: Opening a kettle.properties/repository connection defined against a custom vendor plugin absent at runtime; case-sensitivity mismatch ("postgresql" vs "POSTGRESQL"); plugin id changed after a Pentaho upgrade.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/DatabaseMeta.java:573

  /**
   * Search for the right type of DatabaseInterface object and return it.
   *
   * @param databaseTypeDesc
   *          the type of DatabaseInterface to look for (id or description)
   * @return The requested DatabaseInterface
   *
   * @throws KettleDatabaseException
   *           when the type could not be found or referenced.
   */
  private static final DatabaseInterface findDatabaseInterface( String databaseTypeDesc ) throws KettleDatabaseException {
    PluginRegistry registry = PluginRegistry.getInstance();
    PluginInterface plugin = registry.getPlugin( DatabasePluginType.class, databaseTypeDesc );
    if ( plugin == null ) {
      plugin = registry.findPluginWithName( DatabasePluginType.class, databaseTypeDesc );
    }

    if ( plugin == null ) {
      throw new KettleDatabaseException( "database type with plugin id ["
        + databaseTypeDesc + "] couldn't be found!" );
    }

    return getDatabaseInterfacesMap().get( plugin.getIds()[0] );
  }

  /**
   * Returns the database ID of this database connection if a repository was used before.
   *
   * @return the ID of the db connection.
   */
  @Override
  public ObjectId getObjectId() {
    return databaseInterface.getObjectId();
  }

  @Override
  public void setObjectId( ObjectId id ) {

View on GitHub (pinned to f3058517a1)