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
AvroSink (the file-based sink used by AvroIO.Write) validates metadata map values when preparing the writer: only String, Long, and byte[] are accepted by Avro's DataFileWriter.setMeta. Any other type throws IllegalStateException.
Solutions
- Normalize metadata values to String, Long, or byte[] before building the Write transform
- Replace boxed Integer values with Long
- Convert unsupported types to their String representation
Example fix
// before
metadata.put("ratio", 0.5);
// after
metadata.put("ratio", "0.5"); Defensive patterns
Strategy: type-guard
Validate before calling
for (Map.Entry<String, Object> e : metadata.entrySet()) {
Object v = e.getValue();
if (!(v instanceof String || v instanceof Long || v instanceof byte[]))
throw new IllegalArgumentException(e.getKey() + " is " + v.getClass());
} Type guard
static boolean validMeta(Object v) {
return v instanceof String || v instanceof Long || v instanceof byte[];
} Try / catch
try { sink.prepareWrite(...); } catch (IllegalStateException e) { /* sanitize metadata map */ } Prevention
- Sanitize metadata maps coming from JSON/config sources
- Never box ints into metadata maps without casting to Long
- Add unit tests covering metadata types
When it happens
Trigger: Providing a metadata map with values like Integer, Float, or Boolean to the AvroSink used by AvroIO.Write; thrown during prepareWrite on workers.
Common situations: Same as the AvroIO variant: autoboxed integers, deserialized JSON config where numbers became Integer, dynamically built metadata maps.
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/5a24f007f0f46453.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/io/AvroSink.java:134
CodecFactory codec = dynamicDestinations.getCodec(destination);
Schema schema = dynamicDestinations.getSchema(destination);
Map<String, Object> metadata = dynamicDestinations.getMetadata(destination);
DatumWriter<OutputT> datumWriter =
Optional.ofNullable(dynamicDestinations.getDatumWriterFactory(destination))
.orElse(AvroDatumFactory.of(type))
.apply(schema);
dataFileWriter = new DataFileWriter<>(datumWriter).setCodec(codec);
for (Map.Entry<String, Object> entry : metadata.entrySet()) {
Object v = entry.getValue();
if (v instanceof String) {
dataFileWriter.setMeta(entry.getKey(), (String) v);
} else if (v instanceof Long) {
dataFileWriter.setMeta(entry.getKey(), (Long) v);
} else if (v instanceof byte[]) {
dataFileWriter.setMeta(entry.getKey(), (byte[]) v);
} else {
throw new IllegalStateException(
"Metadata value type must be one of String, Long, or byte[]. Found "
+ v.getClass().getSimpleName());
}
}
dataFileWriter.setSyncInterval(syncInterval);
dataFileWriter.create(schema, Channels.newOutputStream(channel));
}
@Override
public void write(OutputT value) throws Exception {
dataFileWriter.append(value);
}
@Override
protected void finishWrite() throws Exception {
dataFileWriter.flush();
}
}View on GitHub (pinned to 12126d8942)