Description
Given the following Apache Avro schema, the official Rust crate supports it but the popular 'avsc' Javascript package does not.
{
"type": "record",
"name": "ContextGroupACL",
"namespace": "ics",
"fields": [
{
"name": "prid",
"type": "fixed",
"size": 8,
"doc": "Pseudonymous Relationship Identifier"
},
{
"name": "keyId",
"type": "long",
"doc": "User-Assigned Key Identifier used for PRID and encryption"
},
{
"name": "nonce",
"type": "fixed",
"size": 12,
"doc": "Nonce used in encryptedProviderMsaId encryption (12 bytes)"
},
{
"name": "encryptedProviderId",
"type": "bytes",
"maxLength": 10,
"doc": "Encrypted provider Msa id"
}
]
}
Analysis
According to ChatGPT:
This schema is not actually valid Avro as written. The key problem is the two fixed fields. In Avro, fixed is a named type, not a primitive. An inline fixed definition must be an object nested inside the field’s type , and it must include a name . The spec says a field’s type must itself be a schema, and for fixed , the required attributes are name and size . It also says record , enum , and fixed are named types. So spec-compliant Avro would look like this instead:
{
"name": "prid",
"type": {
"type": "fixed",
"name": "Prid",
"size": 8
}
}
Why Rust accepts it anyway
The Apache Rust implementation has had bugs where it accepted schemas that are invalid per the Avro spec instead of rejecting them. There is an Apache Avro Rust bug report explicitly about the Rust parser accepting invalid nested named-type syntax that other Avro implementations reject; that issue was later fixed, which shows the crate has historically been more permissive than the spec. Why avsc rejects it: avsc is interpreting your field literally. With "type": "fixed" as a string, it treats that as a reference to a type named fixed , not as an inline fixed definition with extra field-level properties. Since no named type fixed was declared, it fails. That behavior matches the Avro schema rules above.
A/C
Description
Given the following Apache Avro schema, the official Rust crate supports it but the popular 'avsc' Javascript package does not.
{ "type": "record", "name": "ContextGroupACL", "namespace": "ics", "fields": [ { "name": "prid", "type": "fixed", "size": 8, "doc": "Pseudonymous Relationship Identifier" }, { "name": "keyId", "type": "long", "doc": "User-Assigned Key Identifier used for PRID and encryption" }, { "name": "nonce", "type": "fixed", "size": 12, "doc": "Nonce used in encryptedProviderMsaId encryption (12 bytes)" }, { "name": "encryptedProviderId", "type": "bytes", "maxLength": 10, "doc": "Encrypted provider Msa id" } ] }Analysis
According to ChatGPT:
This schema is not actually valid Avro as written. The key problem is the two fixed fields. In Avro, fixed is a named type, not a primitive. An inline fixed definition must be an object nested inside the field’s type , and it must include a name . The spec says a field’s type must itself be a schema, and for fixed , the required attributes are name and size . It also says record , enum , and fixed are named types. So spec-compliant Avro would look like this instead:
{ "name": "prid", "type": { "type": "fixed", "name": "Prid", "size": 8 } }Why Rust accepts it anyway
The Apache Rust implementation has had bugs where it accepted schemas that are invalid per the Avro spec instead of rejecting them. There is an Apache Avro Rust bug report explicitly about the Rust parser accepting invalid nested named-type syntax that other Avro implementations reject; that issue was later fixed, which shows the crate has historically been more permissive than the spec. Why avsc rejects it: avsc is interpreting your field literally. With "type": "fixed" as a string, it treats that as a reference to a type named fixed , not as an inline fixed definition with extra field-level properties. Since no named type fixed was declared, it fails. That behavior matches the Avro schema rules above.
A/C