{"record":{"id":"e7261c4a4b13799d","repo":"apache/druid","slug":"failed-to-read-avro-message-e7261c","errorCode":null,"errorMessage":"Failed to read Avro message","messagePattern":"Failed to read Avro message","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/SchemaRepoBasedAvroBytesDecoder.java","lineNumber":85,"sourceCode":"  }\n\n  @JsonProperty\n  public SubjectAndIdConverter<SUBJECT, ID> getSubjectAndIdConverter()\n  {\n    return subjectAndIdConverter;\n  }\n\n  @Override\n  public GenericRecord parse(ByteBuffer bytes)\n  {\n    Pair<SUBJECT, ID> subjectAndId = subjectAndIdConverter.getSubjectAndId(bytes);\n    Schema schema = typedRepository.getSchema(subjectAndId.lhs, subjectAndId.rhs);\n    DatumReader<GenericRecord> reader = new GenericDatumReader<>(schema);\n    try (ByteBufferInputStream inputStream = new ByteBufferInputStream(Collections.singletonList(bytes))) {\n      return reader.read(null, DecoderFactory.get().binaryDecoder(inputStream, null));\n    }\n    catch (Exception e) {\n      throw new ParseException(null, e, \"Failed to read Avro message\");\n    }\n  }\n\n  @Override\n  public boolean equals(Object o)\n  {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n\n    SchemaRepoBasedAvroBytesDecoder<?, ?> that = (SchemaRepoBasedAvroBytesDecoder<?, ?>) o;\n\n    if (!Objects.equals(subjectAndIdConverter, that.subjectAndIdConverter)) {\n      return false;\n    }","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/SchemaRepoBasedAvroBytesDecoder.java#L67-L103","documentation":"Thrown by SchemaRepoBasedAvroBytesDecoder.parse when the Avro message cannot be decoded after the schema has been resolved from the subject/id repository. Same family as the other Avro read failures but for the (older) SchemaRepo-based decoder.","triggerScenarios":"parse(ByteBuffer bytes) resolves subject and id via typedRepository, then reader.read() throws — schema mismatch between writer and repository schema, corrupted bytes, or truncated message in the ByteBufferInputStream.","commonSituations":"Messages written under an evolved schema not present/updated in the schema repo; corrupted records on the topic; using this legacy decoder with Confluent wire-format messages it does not understand.","solutions":["Verify the schema stored in the schema repo for the subject/id matches the producer's writer schema","Update or re-register the correct schema version in the repo","Validate the raw message with a standalone Avro tool to detect corruption","Consider migrating to the schema_registry decoder if actually using Confluent wire format"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// verify subject/id resolution before decode\nSchema s = typedRepository.getSchema(subject, id);\nif (s == null) throw new IllegalStateException(\"No schema in repo for \" + subject + \"/\" + id);","typeGuard":null,"tryCatchPattern":"try {\n  GenericRecord record = decoder.parse(bytes);\n} catch (ParseException e) {\n  LOG.warn(e, \"SchemaRepo Avro decode failed; routing to DLQ\");\n}","preventionTips":["Publish every producer schema version to the repo before rollout","Migrate to schema_registry decoder if using Confluent wire format","Checksum-validate large messages end-to-end","Keep writer/reader schema compatibility tests in CI"],"tags":["avro","deserialization","schema-repo"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}