pentaho/pentaho-kettle · error · KettleDatabaseException

Unable to move the resultset forward " + rows + " rows

Error message

Unable to move the resultset forward " + rows + " rows

What it means

KettleDatabaseException wrapper for ResultSet.relative(rows) failures. relative() moves the cursor forward or backward the given number of rows and, like absolute(), requires a scrollable, non-forward-only result set.

Solutions

  1. Request a scrollable result set when creating the Statement
  2. Replace relative() navigation with repeated rs.next() calls or an OFFSET-based re-query
  3. Confirm the result set is open and the connection alive
  4. Verify driver support for scrollable cursors

Example fix

// before
db.relative(rs, rows);
// after
boolean moved = true;
for (int i = 0; i < rows && moved; i++) {
  moved = rs.next();
}
Defensive patterns

Strategy: fallback

Validate before calling

if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
  // use rs.next() loop instead of relative()
}

Type guard

null

Try / catch

try {
  db.relative(rs, rows);
} catch (KettleDatabaseException e) {
  // fallback: advance with rs.next() one row at a time
}

Prevention

When it happens

Trigger: Calling Database.relative(rs, rows) on a TYPE_FORWARD_ONLY result set, after the result set is closed, or on a driver that doesn't implement relative cursor movement.

Common situations: Paging through results with relative() on a default statement; connection or cursor invalidated by timeout; drivers lacking scrollable cursor support.

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/bcc60de08e10c72c. Report an issue: GitHub.

Appendix: source

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

    }

    throw new KettleDatabaseException( "Unable to handle database column '"
      + name + "', on column index " + i + " : not a handled data type" );
  }

  public boolean absolute( ResultSet rs, int position ) throws KettleDatabaseException {
    try {
      return rs.absolute( position );
    } catch ( SQLException e ) {
      throw new KettleDatabaseException( "Unable to move resultset to position " + position, e );
    }
  }

  public boolean relative( ResultSet rs, int rows ) throws KettleDatabaseException {
    try {
      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 );
    }
  }

View on GitHub (pinned to f3058517a1)