pentaho/pentaho-kettle · error · KettleStepException
ERROR0002
ERROR0002
Error message
DatabaseLookup.ERROR0002.UnableToDetermineFieldsOfTable + schemaTable + "]"
What it means
DatabaseLookup.determineFieldsTypesQueryingDb() calls db.getTableFields(schemaTable) to read the lookup table's row metadata. If the database returns null metadata (table or schema.table not found), it throws KettleStepException 'Unable to determine the fields of table' + schemaTable + ']'.
Solutions
- Verify schema.table exists and is spelled correctly (including case) in the step's database connection
- Check the DB user has SELECT/metadata privileges on that table
- Add the correct schema name if the table lives in a non-default schema
- Preview the Database Lookup step to refresh and validate table metadata before running
Example fix
// before (step config) schemaTable = "employees"; // not in default schema // after schemaTable = "hr.employees"; // schema-qualified table
Defensive patterns
Strategy: validation
Validate before calling
// confirm the lookup table exists and is readable before executing
RowMetaInterface fields = db.getTableFields( schemaTable );
if ( fields == null ) {
throw new KettleException( "Lookup table not found or not readable: " + schemaTable );
} Try / catch
try {
rows = db.getLookupRows( ... );
} catch ( KettleStepException e ) {
if ( e.getMessage() != null && e.getMessage().contains( "Unable to determine the fields of table" ) ) {
// check schema.table spelling, grants, then retry
} else { throw e; }
} Prevention
- Qualify lookup tables with schema names to avoid default-schema surprises
- Grant the connection user SELECT (and metadata) access to the lookup table
- Run table existence checks in an init/pre-flight step
- Watch for case-sensitive identifier differences across environments
When it happens
Trigger: processRow() runs a lookup whose key/value types must be determined from the DB and Database.getTableFields() returns null because schemaTable does not exist, is inaccessible to the user, or the schema name is wrong/missing.
Common situations: Lookup table dropped or renamed in the target database; wrong schema prefix after migrating environments (dev vs prod); insufficient grants to read metadata for the table; case-sensitivity issues on uppercase/lowercase table names.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ERROR0001
- GPBulkLoaderMeta.Exception.TableNotFound
- GPBulkLoaderMeta.Exception.TableNotFound
- InsertUpdateMeta.Exception.TableNotFound
- MySQLBulkLoaderMeta.Exception.TableNotFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/364e81a218435d6c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/databaselookup/DatabaseLookup.java:253
// Fill in the types...
for ( int i = 0; i < keyFields.length; i++ ) {
ValueMetaInterface key = fields.searchValueMeta( keyFields[ i ] );
if ( key != null ) {
data.keytypes[ i ] = key.getType();
} else {
throw new KettleStepException( BaseMessages.getString(
PKG, "DatabaseLookup.ERROR0001.FieldRequired5.Exception" )
+ keyFields[ i ]
+ BaseMessages.getString( PKG, "DatabaseLookup.ERROR0001.FieldRequired6.Exception" ) );
}
}
if ( shouldDatabaseReturnValueTypeBeUsed() ) {
useReturnValueTypeFromDatabase( fields );
}
} else {
throw new KettleStepException( BaseMessages.getString(
PKG, "DatabaseLookup.ERROR0002.UnableToDetermineFieldsOfTable" )
+ schemaTable + "]" );
}
}
/*
* Checks whether the return value type of fields should use the ones configured in the database instead
* of the ones chosen in the step UI
* If KETTLE_COMPATIBILITY_DB_LOOKUP_USE_FIELDS_RETURN_TYPE_CHOSEN_IN_UI kettle property is set to "Y"
* the return type of the fields is the one chosen in the step UI.
* If the kettle property is not set or set to "N" then the return type of the fields is the one configured in the database
*/
private boolean shouldDatabaseReturnValueTypeBeUsed() {
String skipLookupReturnFields = getVariable( Const.KETTLE_COMPATIBILITY_DB_LOOKUP_USE_FIELDS_RETURN_TYPE_CHOSEN_IN_UI, "N" );
return !ValueMetaBase.convertStringToBoolean( Const.NVL( skipLookupReturnFields, "N" ) );
}
/*View on GitHub (pinned to f3058517a1)