pentaho/pentaho-kettle · error · KettleStepException
Unable to find key field '" + keyStreamFieldName + "' in…
Error message
Unable to find key field '" + keyStreamFieldName + "' in the input fields
What it means
buildRemoteRowsCursorFromInputInMeta builds the fake cursor row string for the key fields of the LucidDB streaming load. Before appending a key field it looks the field up in the step's input row metadata (prev.searchValueMeta); if a configured key stream field does not exist in the incoming row layout, a KettleStepException with this message is thrown.
Solutions
- Open the LucidDB Streaming Loader dialog and correct the 'key field' names to match the actual upstream output columns.
- Run 'Get Fields' in the step dialog to re-populate the key field list from the real input row metadata.
- Fix the upstream step so it again produces the expected key column (restore a renamed/removed field).
- Re-order steps so the loader's input actually contains the key fields.
Example fix
// before (dialog XML) <field_stream_for_keys>custId_old</field_stream_for_keys> // after <field_stream_for_keys>customer_id</field_stream_for_keys>
Defensive patterns
Strategy: validation
Validate before calling
RowMetaInterface prev = transMeta.getPrevStepFields(stepMeta);
for (String key : meta.getFieldStreamForKeys()) {
if (prev != null && prev.searchValueMeta(key) == null) {
throw new KettleStepException("Key field '" + key + "' missing from upstream output");
}
} Try / catch
try {
meta.getFields(row, name, info, stepMeta, transMeta, metaStore);
} catch (KettleStepException e) {
logError(e.getMessage()); // 'Unable to find key field ...'
throw e;
} Prevention
- Use 'Get Fields' in the dialog instead of typing key field names by hand.
- Re-validate the step after changing any upstream step's output schema.
- Avoid renaming upstream columns without updating downstream loaders.
- Add explicit rename/rename steps when upstream schema changes.
When it happens
Trigger: Calling getFields()/step metadata validation when fieldStreamForKeys[i] names a column that is not present in the output of the preceding step (prev.searchValueMeta returns null).
Common situations: Renaming or removing the key column in the upstream step after configuring the loader; a typo in the key field name in the dialog; upstream step changed its output schema (different table/source).
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
- Field [ ] couldn't be found in the input stream!
- Field [ ] couldn't be found in the input stream!
- GPLoadDataOutput.Exception.FieldNotFound
- Required input field [ + curField.getName() + ] couldn't be…
- SalesforceInsert.CanNotFindField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a063a9a2454b8a54.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/lucid-db-streaming-loader/core/src/main/java/org/pentaho/di/trans/steps/luciddbstreamingloader/LucidDBStreamingLoaderMeta.java:440
boolean suppress_comma = true;
StringBuffer sb = new StringBuffer( 300 );
// Iterate over fieldStreamForKeys[]
for ( int i = 0; i < fieldStreamForKeys.length; i++ ) {
// Add comma to all except the first row
if ( suppress_comma == true ) {
suppress_comma = false;
} else {
sb.append( "," );
}
String keyStreamFieldName = fieldStreamForKeys[i];
ValueMetaInterface keyStreamField = prev.searchValueMeta( fieldStreamForKeys[i] );
if ( keyStreamField == null ) {
throw new KettleStepException( "Unable to find key field '" + keyStreamFieldName + "' in the input fields" );
}
sb.append( buildFakeCursorRowString( keyStreamField, keyStreamFieldName ) ).append( Const.CR );
}
// Iterate over fieldStreamForFields[] (dedup)
for ( int i = 0; i < fieldStreamForFields.length; i++ ) {
// Do not add if it's already in from keys
if ( !isInKeys( fieldStreamForFields[i] ) ) {
// Add comma to all except the first row
if ( suppress_comma == true ) {
suppress_comma = false;
} else {
sb.append( "," );
}
sb.append( buildFakeCursorRowString(View on GitHub (pinned to f3058517a1)