pentaho/pentaho-kettle · error · KettleException
AvroInput.Error.MalformedPathRecord
Error message
AvroInput.Error.MalformedPathRecord
What it means
Kettle exception thrown by AvroNestedReader.convertToKettleValue when the AvroInput field's path part list is exhausted while still trying to convert a record value. It means the configured read path did not correspond to the record structure being processed — no further path segment exists to navigate into the record. The path is malformed relative to the Avro record's schema.
Solutions
- Extend the field's path so it fully traverses the nested record down to a primitive/leaf field (e.g. 'myrecord.fieldName').
- Check the configured path against the actual Avro schema nesting; each record level needs one additional dot-separated part.
- If the path was truncated by escaping issues, verify special characters (dots inside field names) are handled correctly.
- Re-read the schema via the step's field discovery UI to regenerate the correct path.
Example fix
// before Field path: order // stops on a record // after Field path: order.customer_id // traverses into the record
Defensive patterns
Strategy: validation
Validate before calling
// Before running the transformation, verify each field path resolves to a leaf in the schema
if (!pathContainsLeafField(avroSchema, fieldPath)) {
throw new IllegalArgumentException("Path '" + fieldPath + "' does not reach a leaf field; extend it through the record");
} Try / catch
// Wrap conversion per field so one bad path doesn't kill the whole transformation
try {
value = reader.convertToKettleValue(record, schema, field);
} catch (KettleException e) {
if (e.getMessage().contains("MalformedPathRecord")) {
logError("Path for field '" + field.getFieldName() + "' stops at a record; extend the path", e);
}
} Prevention
- Always derive paths from the step's schema discovery instead of typing them by hand
- Remember every record level requires one more dot-separated path part
- Validate paths against the actual file's writer schema, not an assumed one
When it happens
Trigger: convertToKettleValue is called (directly or recursively from setKettleFields) with an AvroInputField whose tempParts list is empty after the value was resolved to a record — i.e. the path string was shorter than the actual nesting depth of the data, or the record was reached with no remaining path parts to select a field from.
Common situations: Users configure an Avro Input step path like 'myfield' when the data contains a nested record at that point requiring a further selector (e.g. 'myfield.innerField'); copy-pasting paths from a differently-versioned schema; paths pointing at a record without drilling into its fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- AvroInputDialog.Error.KettleFileException
- A connection of type PALO is expected
- A connection of type PALO is expected
- A deadlock was detected between steps
- A server socket allocation always has to accompanied by a…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/e108da7e11f45c32.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java:637
/**
* Processes a record at this point in the path.
*
* @param record the record to process
* @param s the current schema at this point in the path
* @param ignoreMissing true if null is to be returned for user fields that don't appear in the schema
* @return the field value or null for out-of-bounds array indexes, non-existent map keys or unsupported avro types.
* @throws KettleException if a problem occurs
*/
public Object convertToKettleValue(AvroInputField avroInputField, GenericData.Record record, Schema s,
Schema defaultSchema, boolean ignoreMissing )
throws KettleException {
if ( record == null ) {
return null;
}
if ( avroInputField.getTempParts().size() == 0 ) {
throw new KettleException( BaseMessages.getString( PKG, "AvroInput.Error.MalformedPathRecord" ) );
}
String part = avroInputField.getTempParts().remove( 0 );
if ( part.charAt( 0 ) == '[' ) {
throw new KettleException(
BaseMessages.getString( PKG, "AvroInput.Error.InvalidPath" ) + avroInputField.getTempParts() );
}
if ( part.indexOf( '[' ) > 0 ) {
String arrayPart = part.substring( part.indexOf( '[' ) );
part = part.substring( 0, part.indexOf( '[' ) );
// put the array section back into location zero
avroInputField.getTempParts().add( 0, arrayPart );
}
// part is a named field of the record
Schema.Field fieldS = s.getField( part );View on GitHub (pinned to f3058517a1)