pentaho/pentaho-kettle · error · KettleDatabaseException

No result set metadata available to retrieve row metadata!

Error message

No result set metadata available to retrieve row metadata!

What it means

KettleDatabaseException thrown by Database.getRowInfo when the ResultSetMetaData argument is null. The library requires valid JDBC result set metadata to build a Kettle RowMetaInterface (column count, types, lengths); without it, row metadata cannot be derived. It is a fail-fast guard before column inspection.

Solutions

  1. Verify the SQL statement actually produces a result set (SELECT) before calling getRow
  2. Check that rs.getMetaData() / the statement was executed successfully before reading rows
  3. Update or replace the JDBC driver with one that returns valid metadata
  4. Catch KettleDatabaseException and treat as 'no result data' rather than retrying

Example fix

// before
Object[] row = db.getRow(rs, false);
// after
ResultSetMetaData md = rs.getMetaData();
if (md != null && md.getColumnCount() > 0) {
  Object[] row = db.getRow(rs, false);
} else {
  // no result set data available
}
Defensive patterns

Strategy: validation

Validate before calling

ResultSetMetaData md = rs.getMetaData();
if (md == null) {
  throw new IllegalStateException("Query produced no result set metadata; is it a SELECT?");
}

Type guard

boolean hasMetadata(ResultSet rs) {
  try { return rs.getMetaData() != null; } catch (SQLException e) { return false; }
}

Try / catch

try {
  row = db.getRow(rs, false);
} catch (KettleDatabaseException e) {
  if (e.getMessage().contains("No result set metadata")) {
    // treat as empty/no-data result
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling getRowInfo/getRow with a ResultSet whose getMetaData() returned null (e.g. statement produced no result set, DDL execution results, or a driver that returns null metadata). Also thrown when Database.getRow(ResultSet, boolean) internally receives null from rs.getMetaData().

Common situations: Executing non-SELECT statements then trying to read rows; JDBC drivers (some custom/old drivers) that return null ResultSetMetaData; calling getRow() on a closed or never-executed statement's result set.

Related errors


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

Appendix: source

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

    } catch ( SQLException ex ) {
      throw new KettleDatabaseException( "Couldn't close query: resultset or prepared statements", ex );
    }
  }

  /**
   * Build the row using ResultSetMetaData rsmd
   *
   * @param rm             The resultset metadata to inquire
   * @param ignoreLength   true if you want to ignore the length (workaround for MySQL bug/problem)
   * @param lazyConversion true if lazy conversion needs to be enabled where possible
   */
  private RowMetaInterface getRowInfo( ResultSetMetaData rm, boolean ignoreLength, boolean lazyConversion )
    throws KettleDatabaseException {
    try {
      log.snap( Metrics.METRIC_DATABASE_GET_ROW_META_START, databaseMeta.getName() );

      if ( rm == null ) {
        throw new KettleDatabaseException( "No result set metadata available to retrieve row metadata!" );
      }

      RowMetaInterface rowMeta = new RowMeta();

      try {
        int nrcols = rm.getColumnCount();
        for ( int i = 1; i <= nrcols; i++ ) {
          ValueMetaInterface valueMeta = getValueFromSQLType( rm, i, ignoreLength, lazyConversion );
          rowMeta.addValueMeta( valueMeta );
        }
        return rowMeta;
      } catch ( SQLException ex ) {
        throw new KettleDatabaseException( "Error getting row information from database: ", ex );
      }
    } finally {
      log.snap( Metrics.METRIC_DATABASE_GET_ROW_META_STOP, databaseMeta.getName() );
    }
  }

View on GitHub (pinned to f3058517a1)