pentaho/pentaho-kettle · error · KettleDatabaseException

No valid database connection defined!

Error message

No valid database connection defined!

What it means

Database.normalConnect throws KettleDatabaseException("No valid database connection defined!") when the Database instance has no databaseMeta set. A Database object cannot open any connection without its DatabaseMeta configuration object.

Solutions

  1. Set a DatabaseMeta before connecting: database.setDatabaseMeta(dbMeta) or use the Database(DatabaseMeta) constructor
  2. Verify the metadata came from a valid repository/shared connection definition
  3. Guard with a null check on getDatabaseMeta() before calling connect()

Example fix

// before
Database db = new Database( loggingObject, null );
db.connect();

// after
Database db = new Database( loggingObject, databaseMeta );
if ( db.getDatabaseMeta() != null ) {
  db.connect();
}
Defensive patterns

Strategy: validation

Validate before calling

if ( databaseMeta == null ) {
  throw new IllegalArgumentException( "DatabaseMeta must be set before connect()" );
}

Type guard

if ( database == null || database.getDatabaseMeta() == null ) {
  return; // not configured; skip connection attempt
}

Try / catch

try {
  db.connect();
} catch ( KettleDatabaseException e ) {
  log.error( "Connection not configured: " + e.getMessage() );
}

Prevention

When it happens

Trigger: Calling connect() or normalConnect(partitionId) on a Database created without a DatabaseMeta, or after databaseMeta was set to null; also shareConnectionWith/test paths that operate on an unconfigured Database.

Common situations: Constructing new Database() with the no-arg constructor and forgetting setDatabaseMeta(); deserialization/transformation metadata loading that left databaseMeta null; refactorings that lost the metadata assignment before connect.

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


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:498

    anotherDb.copy = this.opened;
  }

  /**
   * Open the database connection. The algorithm is:
   * <ol>
   * <li>If <code>databaseMeta.getAccessType()</code> returns
   * <code>DatabaseMeta.TYPE_ACCESS_JNDI</code>, then the connection's datasource is looked up in JNDI </li>
   * <li>If <code>databaseMeta.isUsingConnectionPool()</code>, then the connection's datasource is looked up in the
   * pool</li>
   * <li>otherwise, the connection is established via {@linkplain java.sql.DriverManager}</li>
   * </ol>
   *
   * @param partitionId the partition ID in the cluster to connect to.
   * @throws KettleDatabaseException if something went wrong.
   */
  public void normalConnect( String partitionId ) throws KettleDatabaseException {
    if ( databaseMeta == null ) {
      throw new KettleDatabaseException( "No valid database connection defined!" );
    }

    try {
      if ( databaseMeta.getAccessType() == DatabaseMeta.TYPE_ACCESS_JNDI ) {
        log.logDetailed( "Acquiring JNDI connection for database [" + databaseMeta.getName() + "]..." );
        long startJndi = System.currentTimeMillis();
        this.connection = getDataSource( partitionId ).getConnection();
        log.logDetailed( "JNDI connection acquired for database [" + databaseMeta.getName() + "] in " + ( System.currentTimeMillis() - startJndi ) + " ms" );
      } else if ( databaseMeta.isUsingConnectionPool() ) {
        log.logDetailed( "Acquiring pooled connection for database [" + databaseMeta.getName() + "]..." );
        long startPool = System.currentTimeMillis();
        this.connection = getDataSource( partitionId ).getConnection();
        log.logDetailed( "Pooled connection acquired for database [" + databaseMeta.getName() + "] in " + ( System.currentTimeMillis() - startPool ) + " ms" );
        if ( getConnection().getAutoCommit() != isAutoCommit() ) {
          setAutoCommit( isAutoCommit() );
        }
      } else {
        // using non-jndi and non-pooled connection -- just a simple JDBC

View on GitHub (pinned to f3058517a1)