pentaho/pentaho-kettle · error · KettleDatabaseException

Unable to move resultset to the first position

Error message

Unable to move resultset to the first position

What it means

Wrapper error from Database.first(): the JDBC ResultSet.first() call threw an SQLException (e.g. the result set is TYPE_FORWARD_ONLY, already closed, or the driver does not support cursor positioning). The original SQLException is chained as the cause.

Solutions

  1. Create the Statement with TYPE_SCROLL_INSENSITIVE (note: this may buffer results in memory)
  2. Re-execute the query instead of rewinding a forward-only result set
  3. Check rs.getType() before calling first()
  4. Avoid streaming mode settings that force TYPE_FORWARD_ONLY

Example fix

// before
Statement st = conn.createStatement();
db.first(rs);
// after
Statement st = conn.createStatement(
  ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery(sql);
db.first(rs);
Defensive patterns

Strategy: validation

Validate before calling

if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
  throw new IllegalStateException("first() needs a scrollable result set; re-execute instead");
}

Type guard

null

Try / catch

try {
  db.first(rs);
} catch (KettleDatabaseException e) {
  // fallback: re-execute the query for a fresh cursor
}

Prevention

When it happens

Trigger: Calling Database.first(rs) on a forward-only result set, a closed result set, or with a driver that doesn't implement first().

Common situations: Resetting iteration to the beginning on a default statement; driver limitations (e.g. some streaming configurations force forward-only); result set closed after connection issues.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

      return rs.relative( rows );
    } catch ( SQLException e ) {
      throw new KettleDatabaseException( "Unable to move the resultset forward " + rows + " rows", e );
    }
  }

  public void afterLast( ResultSet rs ) throws KettleDatabaseException {
    try {
      rs.afterLast();
    } catch ( SQLException e ) {
      throw new KettleDatabaseException( "Unable to move resultset to after the last position", e );
    }
  }

  public void first( ResultSet rs ) throws KettleDatabaseException {
    try {
      rs.first();
    } catch ( SQLException e ) {
      throw new KettleDatabaseException( "Unable to move resultset to the first position", e );
    }
  }

  /**
   * Get a row from the resultset. Do not use lazy conversion
   *
   * @param rs The resultset to get the row from
   * @return one row or null if no row was found on the resultset or if an error occurred.
   */
  public Object[] getRow( ResultSet rs ) throws KettleDatabaseException {
    return getRow( rs, false );
  }

  /**
   * Get a row from the resultset.
   *
   * @param rs             The resultset to get the row from
   * @param lazyConversion set to true if strings need to have lazy conversion enabled

View on GitHub (pinned to f3058517a1)