pentaho/pentaho-kettle · error · KettleException
AvroInput.Error.JsonDecoderError
Error message
AvroInput.Error.JsonDecoderError
What it means
When the Avro Input step is configured to decode Avro from a JSON-encoded incoming field, DecoderFactory.jsonDecoder(schema, fieldValue) threw an IOException. AvroNestedReader wraps this in a KettleException, meaning the field's string content is not valid JSON matching the configured schema.
Solutions
- Log/inspect the raw field value for the failing row to confirm it is valid, complete JSON.
- Verify the Avro schema configured in the step matches the JSON payload structure.
- Check the 'field to decode' index/selection points at the correct incoming column.
- If the data is actually binary Avro, switch the step from JSON to binary decoding mode.
Example fix
// before: field contains malformed/partial JSON
String fieldValue = fieldMeta.getString(incoming[m_fieldToDecodeIndex]);
// after: guard upstream
if (fieldValue == null || !fieldValue.trim().startsWith("{")) throw new KettleException("not valid avro-json: " + fieldValue); Defensive patterns
Strategy: validation
Validate before calling
String json = fieldMeta.getString(row[fieldIndex]);
try { new org.json.JSONTokener(json).nextValue(); } catch (Exception e) {
throw new IllegalArgumentException("field is not valid JSON");
} Try / catch
try {
rows = reader.avroObjectToKettle(row, space);
} catch (KettleException e) {
if (e.getMessage().contains("JsonDecoderError")) { logRawValue(row[fieldIndex]); routeToErrorStream(row, e); } else throw e;
} Prevention
- Confirm the decode mode (JSON vs binary) matches the payload format.
- Verify the configured schema matches the JSON payload structure.
- Log a sample payload when configuring the step.
When it happens
Trigger: m_jsonEncoded is true and the string read from incoming[m_fieldToDecodeIndex] cannot be decoded as Avro JSON against m_schemaToUse — malformed JSON, wrong encoding, or JSON shape not matching the schema.
Common situations: Upstream sends truncated or escaped JSON; field contains plain text/binary instead of JSON; schema configured in the step differs from what the JSON payload represents (missing required fields, wrong types).
Related errors
- Failed to parse SSO provider response
- Invalid schema JSON:
- Not a valid default value " + defaultValue + " for data…
- The default value " + defaultValue + " should be of format…
- The default value " + defaultValue + " should be of format…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/fd9dfeeee77d80ff.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java:1489
// just resize the existing incoming array (if necessary) and return
// the incoming values
result[ 0 ] = RowDataUtil.resizeArray( incoming, m_outputRowMeta.size() );
return result;
}
// if necessary, set the current datum reader and top level structure
// for the incoming schema
if ( m_schemaInField ) {
ValueMetaInterface schemaMeta = m_incomingRowMeta.getValueMeta( m_schemaFieldIndex );
String schemaToUse = schemaMeta.getString( incoming[ m_schemaFieldIndex ] );
setSchemaToUse( schemaToUse, m_cacheSchemas, space );
}
if ( m_jsonEncoded ) {
try {
String fieldValue = fieldMeta.getString( incoming[ m_fieldToDecodeIndex ] );
m_decoder = m_factory.jsonDecoder( m_schemaToUse, fieldValue );
} catch ( IOException e ) {
throw new KettleException(
BaseMessages.getString( PKG,
"AvroInput.Error.JsonDecoderError" ) );
}
} else {
byte[] fieldValue = fieldMeta.getBinary( incoming[ m_fieldToDecodeIndex ] );
m_decoder = m_factory.binaryDecoder( fieldValue, null );
}
}
if ( m_topLevelRecord != null ) {
// special case for top-level record. In case we actually
// have a top level union, reassign the record so that
// we have the correctly populated object in the case
// where our last record instance can't be reused (i.e.
// the next record read is a different one from the union
// than the last one).
m_topLevelRecord = (GenericData.Record) m_datumReader.read( m_topLevelRecord, m_decoder );View on GitHub (pinned to f3058517a1)