pentaho/pentaho-kettle · error · KettleException
FuzzyMatch.Exception.CouldnotFindLookField
Error message
FuzzyMatch.Exception.CouldnotFindLookField
What it means
FuzzyMatch.readLookupValues validates the info (lookup) stream's row metadata and throws this KettleException when the configured Lookup Field cannot be found in the lookup stream (indexOfValue < 0). It fails fast at the first row instead of silently matching against a missing column.
Solutions
- Open the Fuzzy Match step and re-select the Lookup field from the dropdown so it matches the actual lookup-stream column.
- Check the step feeding the lookup side of the hop and confirm the column name (case-sensitive) is produced there.
- If a variable is used for the field name, verify the variable resolves correctly (add a 'Get Variables' log or use environmentSubstitute debugging).
- Re-run after adding the missing column via a Select Values or other step if the field is genuinely required.
Example fix
// before Lookup field: 'cust_id' // after (column actually named 'customer_id' in lookup stream) Lookup field: 'customer_id'
Defensive patterns
Strategy: validation
Validate before calling
// Before the Fuzzy Match step, assert the lookup field exists:
int idx = lookupRowMeta.indexOfValue(lookupFieldName);
if (idx < 0) {
throw new KettleException("Lookup field not found in lookup stream: " + lookupFieldName);
} Try / catch
try {
processRow();
} catch (KettleException e) {
if (e.getMessage().contains("CouldnotFindLookField")) {
logError("Check Fuzzy Match lookup field config vs lookup stream layout: " + e.getMessage());
}
throw e;
} Prevention
- Re-open the step dialog after changing upstream steps so field lists refresh.
- Avoid hardcoded field names; prefer selecting from the dropdown.
- Preview the lookup stream before running the full transformation.
- Watch for renames introduced by Select Values steps.
When it happens
Trigger: The Fuzzy Match step's 'Lookup field' setting names a column that does not exist in the second (lookup) input stream when the first lookup row is read in processRow.
Common situations: Typo in the lookup field name; upstream lookup-stream step renamed/removed the column; field was added as environment variable placeholder that didn't resolve; copying a transformation between environments where stream layouts differ.
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
- FuzzyMatch.Exception.CouldnotFindMainField
- A connection of type PALO is expected
- A server socket allocation always has to accompanied by…
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d442ea16e5e59533.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/fuzzymatch/FuzzyMatch.java:89
if ( isDetailed() ) {
logDetailed( BaseMessages.getString( PKG, "FuzzyMatch.Log.ReadingFromStream" )
+ data.infoStream.getStepname() + "]" );
}
boolean firstRun = true;
// Which row set do we read from?
//
RowSet rowSet = findInputRowSet( data.infoStream.getStepname() );
Object[] rowData = getRowFrom( rowSet ); // rows are originating from "lookup_from"
while ( rowData != null ) {
if ( firstRun ) {
data.infoMeta = rowSet.getRowMeta().clone();
// Check lookup field
int indexOfLookupField = data.infoMeta.indexOfValue( environmentSubstitute( meta.getLookupField() ) );
if ( indexOfLookupField < 0 ) {
// The field is unreachable !
throw new KettleException( BaseMessages.getString(
PKG, "FuzzyMatch.Exception.CouldnotFindLookField", meta.getLookupField() ) );
}
data.infoCache = new RowMeta();
ValueMetaInterface keyValueMeta = data.infoMeta.getValueMeta( indexOfLookupField );
keyValueMeta.setStorageType( ValueMetaInterface.STORAGE_TYPE_NORMAL );
data.infoCache.addValueMeta( keyValueMeta );
// Add key
data.indexOfCachedFields[0] = indexOfLookupField;
// Check additional fields
if ( data.addAdditionalFields ) {
ValueMetaInterface additionalFieldValueMeta;
for ( int i = 0; i < meta.getValue().length; i++ ) {
int fi = i + 1;
data.indexOfCachedFields[fi] = data.infoMeta.indexOfValue( meta.getValue()[i] );
if ( data.indexOfCachedFields[fi] < 0 ) {
// The field is unreachable !
throw new KettleException( BaseMessages.getString(View on GitHub (pinned to f3058517a1)