apache/flink · error · UnsupportedOperationException
Expected two fields for the map (key/value), but got: {}
Error message
Expected two fields for the map (key/value), but got: {} What it means
When building a writer for a protobuf map field, the nested message type must have exactly two fields (key and value) per protobuf's map encoding. Any other field count throws UnsupportedOperationException from createMapWriter.
Source
Thrown at flink-formats/flink-parquet/src/main/java/org/apache/flink/formats/parquet/protobuf/PatchedProtoWriteSupport.java:432
@Override
public Optional<GroupType> visit(
LogicalTypeAnnotation.MapLogicalTypeAnnotation
mapLogicalType) {
return ofNullable(
type.asGroupType()
.getType("key_value")
.asGroupType()
.getType("value")
.asGroupType());
}
})
.orElse(type.asGroupType());
}
private MapWriter createMapWriter(FieldDescriptor fieldDescriptor, Type type) {
List<FieldDescriptor> fields = fieldDescriptor.getMessageType().getFields();
if (fields.size() != 2) {
throw new UnsupportedOperationException(
"Expected two fields for the map (key/value), but got: " + fields);
}
// KeyFieldWriter
FieldDescriptor keyProtoField = fields.get(0);
FieldWriter keyWriter = createWriter(keyProtoField, type);
keyWriter.setFieldName(keyProtoField.getName());
keyWriter.setIndex(0);
// ValueFieldWriter
FieldDescriptor valueProtoField = fields.get(1);
FieldWriter valueWriter = createWriter(valueProtoField, type);
valueWriter.setFieldName(valueProtoField.getName());
valueWriter.setIndex(1);
return new MapWriter(keyWriter, valueWriter);
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Define the field as a proper proto map: map<K,V> field = N; so the compiler generates the 2-field MapEntry
- If using a hand-built Descriptor for a map-like structure, ensure the entry message has exactly key and value fields
- For repeated key-value groups that are not maps, use repeated message instead of map semantics
Example fix
// before (hand-built descriptor entry with 3 fields)
// message BadEntry { string key = 1; string value = 2; string extra = 3; }
// after
// message GoodEntry { string key = 1; string value = 2; }
// or in proto: map<string, string> entries = 1; Defensive patterns
Strategy: validation
Validate before calling
FieldDescriptor fd = ...;
if (fd.isMapField() && fd.getMessageType().getFields().size() != 2) { throw new IllegalArgumentException("map entry must have exactly key+value: " + fd.getFullName()); } Prevention
- Use compiler-generated map fields (map<K,V>) rather than hand-built entry descriptors
- Validate hand-constructed Descriptors before handing them to the parquet writer
- Add a schema smoke-test that writes one sample message per top-level type in CI
When it happens
Trigger: A .proto map field whose entry message somehow has != 2 fields - typically hand-constructed Descriptors, proto schema manipulation, or a map-like repeated group message passed where a true map is expected.
Common situations: Custom Descriptor construction, dynamic descriptors built at runtime, or protobuf editions/features producing unexpected map entry shapes.
Related errors
- Unknown type with descriptor "{}" and type "{}."
- JSON format doesn't support non-string as key type of map. T
- JSON format doesn't support non-string as key type of map. T
- JSON format doesn't support non-string as key type of map. T
- Please use AvroParquetReaders.forGenericRecord(Class<T>) for
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/be3bafe8e1dccf6c.
Report an issue: GitHub.