apache/beam · error · IllegalStateException
Metadata value type must be one of String, Long, or byte[]…
Error message
Metadata value type must be one of String, Long, or byte[]. Found ${v.getClass().getSimpleName()} What it means
When writing Avro container files through AvroIO.Write, user metadata values may only be String, Long, or byte[] — the types Avro's DataFileWriter.setMeta supports. Any other value type throws IllegalStateException at write setup time.
Solutions
- Convert numeric metadata values to Long explicitly ((long) intValue)
- Convert boolean/double values to String or byte[] before passing
- Whitelist/transform the metadata map at pipeline construction to the three supported types
Example fix
// before
metadata.put("count", 42); // Integer
// after
metadata.put("count", 42L); // Long Defensive patterns
Strategy: type-guard
Validate before calling
metadata.values().forEach(v -> {
if (!(v instanceof String || v instanceof Long || v instanceof byte[]))
throw new IllegalArgumentException("Bad metadata type: " + v.getClass());
}); Type guard
static boolean isAvroMetaType(Object v) {
return v instanceof String || v instanceof Long || v instanceof byte[];
} Try / catch
try { writer.create(schema, out); } catch (IllegalStateException e) { /* normalize metadata and retry */ } Prevention
- Declare metadata maps as Map<String, Object> only after normalizing types
- Use explicit L suffix for numeric metadata
- Centralize metadata construction in one typed builder
When it happens
Trigger: Passing a Map<String, Object> with metadata (withMetadata) whose values are e.g. Integer, Double, Boolean, or Float to AvroIO.Write.
Common situations: Auto-boxed ints from Java literals (Integer instead of Long), JSON-parsed metadata with mixed types, or configuration maps built generically without normalizing types.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Metadata value type must be one of String, Long, or byte[]…
- Can't convert 'string' map keys to
- Does not support converting unknown type value: " +…
- Error converting field :
- is not primitive type.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/706e20e64bb2efde.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/io/AvroIO.java:2179
if (getRecordFormatter() != null) {
datumWriter = new FormattedDatumWriter<>(schema, getRecordFormatter());
} else if (getDatumWriterFactory() != null) {
datumWriter = getDatumWriterFactory().apply(schema);
} else {
datumWriter = new ReflectDatumWriter<>(schema);
}
writer = new DataFileWriter<>(datumWriter);
writer.setCodec(getCodec().getCodec());
for (Map.Entry<String, Object> entry : getMetadata().entrySet()) {
Object v = entry.getValue();
if (v instanceof String) {
writer.setMeta(entry.getKey(), (String) v);
} else if (v instanceof Long) {
writer.setMeta(entry.getKey(), (Long) v);
} else if (v instanceof byte[]) {
writer.setMeta(entry.getKey(), (byte[]) v);
} else {
throw new IllegalStateException(
"Metadata value type must be one of String, Long, or byte[]. Found "
+ v.getClass().getSimpleName());
}
}
writer.create(schema, Channels.newOutputStream(channel));
}
@Override
public void write(ElementT element) throws IOException {
writer.append(element);
}
@Override
public void flush() throws IOException {
writer.flush();
}
}
View on GitHub (pinned to 12126d8942)