pentaho/pentaho-kettle · error · KettleDatabaseException
Entry to update with following key could not be found:
Error message
Entry to update with following key could not be found:
What it means
Thrown by the Update step's lookupValues when a lookup row is not found in the target table and the step is configured to error (not insert/skip). It is a KettleDatabaseException whose message includes the stringified lookup parameter row, identifying the key values that were absent.
Solutions
- Check the step's 'Lookup key not found' handling setting and choose insert/skip/ignore instead of error if missing keys are expected
- Verify key stream and lookup field names and data types match the target table columns exactly
- Pre-validate that key values exist in the target table before updating (e.g. a lookup/table input step)
- Inspect the lookup row values in the message to find which key values are missing and fix upstream data
Example fix
// before: step configured to throw on missing key throw new KettleDatabaseException(...KeyCouldNotFound + data.lookupParameterRowMeta.getString(lookupRow)); // after (step dialog): set 'Error on lookup key not found' = false, or route the error via putError/hop to an insert path
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check key existence in target table before update flow
// Or in a UDJC/Script step:
if (row exist check via lookup step fails) { route row to insert path or putError(); } Try / catch
try { updateStepResult } catch (KettleDatabaseException e) { if (e.getMessage().contains("KeyCouldNotFound")) { /* route row to insert path */ } else { throw e; } } Prevention
- Configure 'lookup key not found' as insert/skip rather than error when missing keys are expected
- Match key field data types exactly with target columns
- Use an error handling hop to capture UPD001 errors instead of failing the transformation
When it happens
Trigger: During transformation execution, the prepared lookup SELECT returns no rows for the incoming stream row's key values while 'error on key not found' behavior is selected (the else-branch after putError).
Common situations: Running an update where the target row was deleted between steps; mismatched key field types (e.g. string '1' vs numeric 1) so lookups silently miss; feeding rows for keys that were never inserted.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Trans.Exception.ConnectionCouldNotBeFound
- Trans.Exception.ErrorCalculatingDateRange
- Trans.Exception.ErrorWritingLogRecordToTable
- Trans.Exception.UnableToBeginProcessingTransformation
- Trans.Exception.UnableToWriteMetricsInformationToLogTable
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/c9e2396bd9edfdf0.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/update/Update.java:120
*/
if ( !meta.isErrorIgnored() ) {
if ( getStepMeta().isDoingErrorHandling() ) {
outputRow = null;
if ( data.stringErrorKeyNotFound == null ) {
data.stringErrorKeyNotFound =
BaseMessages.getString( PKG, "Update.Exception.KeyCouldNotFound" )
+ data.lookupParameterRowMeta.getString( lookupRow );
data.stringFieldnames = "";
for ( int i = 0; i < data.lookupParameterRowMeta.size(); i++ ) {
if ( i > 0 ) {
data.stringFieldnames += ", ";
}
data.stringFieldnames += data.lookupParameterRowMeta.getValueMeta( i ).getName();
}
}
putError( rowMeta, row, 1L, data.stringErrorKeyNotFound, data.stringFieldnames, "UPD001" );
} else {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "Update.Exception.KeyCouldNotFound" )
+ data.lookupParameterRowMeta.getString( lookupRow ) );
}
} else {
if ( log.isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "Update.Log.KeyCouldNotFound" )
+ data.lookupParameterRowMeta.getString( lookupRow ) );
}
if ( !Utils.isEmpty( meta.getIgnoreFlagField() ) ) { // set flag field!
outputRow[rowMeta.size()] = Boolean.FALSE;
}
}
} else {
if ( !meta.isSkipLookup() ) {
if ( log.isRowLevel() ) {
logRowlevel( BaseMessages.getString( PKG, "Update.Log.FoundRow" )
+ data.lookupReturnRowMeta.getString( add ) );
}View on GitHub (pinned to f3058517a1)