pentaho/pentaho-kettle · error · KettleException
IfNull.Log.CanNotFindField
Error message
IfNull.Log.CanNotFindField
What it means
The If Null step's processRow() resolves each configured field name to an index in the output row metadata. When a configured field name is not present in the incoming row stream, data.fieldnrs[i] is -1, an error is logged, and a KettleException with this message (containing the offending field name) is thrown, aborting the transformation.
Solutions
- Open the If Null step dialog, remove/re-select the missing field, and re-save the transformation
- Check the upstream step that produces the field and confirm the field actually reaches this step
- Enable/inspect the preview of the previous step to see the actual row field names
- Make field names case-consistent (Kettle field lookup is case-sensitive)
Example fix
// before (If Null step config referencing removed column)
fields: [ { fieldName: "amnt" } ]
// after (match actual upstream column)
fields: [ { fieldName: "amount" } ] Defensive patterns
Strategy: validation
Validate before calling
for (String f : ifNullMeta.getFieldNames()) { if (prevRowMeta.indexOfValue(f) < 0) throw new IllegalStateException("Missing field: " + f); } Type guard
boolean fieldExists(RowMetaInterface row, String name) { return row != null && row.indexOfValue(name) >= 0; } Try / catch
try { trans.execute(null); } catch (KettleException e) { if (e.getMessage().contains("CanNotFindField")) { fixFieldMapping(); } else { throw e; } } Prevention
- Preview upstream rows to confirm field names before configuring the step
- Use the dialog field picker instead of typing names
- Keep field names case-consistent across steps
When it happens
Trigger: processRow runs and meta.getFields() contains a field name that indexOfValue() cannot find in the output row metadata — i.e., the configured 'set value if null' field does not exist in the input stream.
Common situations: Upstream step renamed or removed the field; field name typo in the If Null dialog; dynamic field layout from a table input where the column doesn't exist; case-sensitivity mismatch in field 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
- Field [ ] couldn't be found in the input stream!
- Unable to find field [] in the input rows
- A deadlock was detected between steps
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ee829bf8628ab0ca.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/ifnull/IfNull.java:91
// For String to <type> conversions, we allocate a conversion meta data row as well...
//
data.convertRowMeta = data.outputRowMeta.cloneToType( ValueMetaInterface.TYPE_STRING );
if ( meta.isSelectFields() ) {
// Consider only selected fields
if ( meta.getFields() != null && meta.getFields().length > 0 ) {
int fieldsLength = meta.getFields().length;
data.fieldnrs = new int[fieldsLength];
data.defaultValues = new String[fieldsLength];
data.defaultMasks = new String[fieldsLength];
data.setEmptyString = new boolean[fieldsLength];
for ( int i = 0; i < meta.getFields().length; i++ ) {
data.fieldnrs[i] = data.outputRowMeta.indexOfValue( meta.getFields()[i].getFieldName() );
if ( data.fieldnrs[i] < 0 ) {
logError( BaseMessages.getString( PKG, "IfNull.Log.CanNotFindField", meta.getFields()[i]
.getFieldName() ) );
throw new KettleException( BaseMessages.getString( PKG, "IfNull.Log.CanNotFindField", meta.getFields()[i]
.getFieldName() ) );
}
data.defaultValues[i] = environmentSubstitute( meta.getFields()[i].getReplaceValue() );
data.defaultMasks[i] = environmentSubstitute( meta.getFields()[i].getReplaceMask() );
data.setEmptyString[i] = meta.getFields()[i].isSetEmptyString();
}
} else {
throw new KettleException( BaseMessages.getString( PKG, "IfNull.Log.SelectFieldsEmpty" ) );
}
} else if ( meta.isSelectValuesType() ) {
// Consider only select value types
if ( meta.getValueTypes() != null && meta.getValueTypes().length > 0 ) {
// return the real default values
int typeLength = meta.getValueTypes().length;
data.defaultValues = new String[typeLength];
data.defaultMasks = new String[typeLength];
data.setEmptyString = new boolean[typeLength];
View on GitHub (pinned to f3058517a1)