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
- Set a DatabaseMeta before connecting: database.setDatabaseMeta(dbMeta) or use the Database(DatabaseMeta) constructor
- Verify the metadata came from a valid repository/shared connection definition
- 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
- Always construct Database with a DatabaseMeta via constructor or setDatabaseMeta
- Validate metadata loading (repository/shared XML) before instantiating Database
- Null-check getDatabaseMeta() in helper code that wraps connect()
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
- AbortMeta.Exception.UnableToSaveStepInfoToRepository
- AccessInputMeta.Exception.ErrorReadingRepository
- AddSequence.Exception.CouldNotFindNextValueForSequence
- AddSequence.Exception.ErrorReadingSequence
- AddSequenceMeta.Exception.UnableToReadStepInfo
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 JDBCView on GitHub (pinned to f3058517a1)