pentaho/pentaho-kettle · error · KettleDatabaseException

Database.UnableToCheckIfConnectionPoolExists.Exception

Error message

Database.UnableToCheckIfConnectionPoolExists.Exception

What it means

ConnectionPoolUtil.isDataSourceRegistered wraps any exception encountered while checking the shared DataSource registry into 'Database.UnableToCheckIfConnectionPoolExists.Exception'. It means the registration lookup (computing the data source name or checking old-config) blew up, so pool status can't be determined.

Solutions

  1. Inspect the chained cause of the KettleDatabaseException to find the real failure
  2. Validate the DatabaseMeta is fully populated (name, connection details) before calling getDataSource
  3. Ensure partitionId is valid/non-null where partitioning is used
  4. Fix the root cause inside getDataSourceName/hasOldConfig if the exception is reproducible with valid input

Example fix

// before
DataSource ds = ConnectionPoolUtil.getDataSource( log, possiblyIncompleteDbMeta, partitionId );
// after
if ( dbMeta.getName() == null || dbMeta.getHostname() == null ) {
  throw new KettleException( "DatabaseMeta incomplete: name and hostname are required for pooling" );
}
DataSource ds = ConnectionPoolUtil.getDataSource( log, dbMeta, partitionId );
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate DatabaseMeta before touching the pool
if ( dbMeta == null || dbMeta.getName() == null ) {
  throw new IllegalArgumentException( "DatabaseMeta with a non-null name is required for connection pooling" );
}

Type guard

boolean poolReady( DatabaseMeta dbMeta ) { return dbMeta != null && dbMeta.getName() != null && !dbMeta.getName().trim().isEmpty(); }

Try / catch

try { ds = ConnectionPoolUtil.getDataSource( log, dbMeta, partitionId ); } catch ( KettleDatabaseException e ) { log.error( "Pool registration check failed; cause: " + e.getCause(), e ); throw new IllegalStateException( e ); }

Prevention

When it happens

Trigger: getDataSource → isDataSourceRegistered throws when getDataSourceName(dbMeta, partitionId) or hasOldConfig(...) throws — e.g. DatabaseMeta fields null/invalid while composing the pool name, or an unexpected error inside hasOldConfig's config comparison.

Common situations: Null or incomplete DatabaseMeta passed to getDataSource (missing name/attributes); corrupted partitionId; unexpected RuntimeException from config comparison logic; concurrent modification of the registry.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/database/ConnectionPoolUtil.java:77

  public static final String LOG_ABANDONED = "logAbandoned";
  private static Class<?> PKG = Database.class; // for i18n purposes, needed by Translator2!!

  private static ConcurrentMap<String, BasicDataSource> dataSources = new ConcurrentHashMap<String, BasicDataSource>();
  private static Map<String, Properties> dataSourcesAttributesMap = new HashMap<>();

  // PDI-12947
  private static final ReentrantLock lock = new ReentrantLock();

  public static final int defaultInitialNrOfConnections = 5;
  public static final int defaultMaximumNrOfConnections = 10;

  private static boolean isDataSourceRegistered( DatabaseMeta dbMeta, String partitionId )
    throws KettleDatabaseException {
    try {
      String name = getDataSourceName( dbMeta, partitionId );
      return dataSources.containsKey( name ) && hasOldConfig( dbMeta, partitionId );
    } catch ( Exception e ) {
      throw new KettleDatabaseException( BaseMessages.getString( PKG,
          "Database.UnableToCheckIfConnectionPoolExists.Exception" ), e );
    }
  }

  public static DataSource getDataSource( LogChannelInterface log, DatabaseMeta dbMeta, String partitionId ) throws KettleDatabaseException {
    int initialSize = dbMeta.getInitialPoolSize();
    int maximumSize = dbMeta.getMaximumPoolSize();

    lock.lock();
    try {
      if ( !isDataSourceRegistered( dbMeta, partitionId ) ) {
        addPoolableDataSource( log, dbMeta, partitionId, initialSize, maximumSize );
      }
    } finally {
      lock.unlock();
    }
    return dataSources.get( getDataSourceName( dbMeta, partitionId ) );
  }

View on GitHub (pinned to f3058517a1)