{"record":{"id":"df161a4bdceca568","repo":"apache/iceberg","slug":"avro-format-doesn-t-support-non-string-as-key-type-df161a","errorCode":null,"errorMessage":"Avro format doesn't support non-string as key type of map. The key type is: %s","messagePattern":"Avro format doesn't support non-string as key type of map\\. The key type is: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/formats/avro/typeutils/AvroSchemaConverter.java","lineNumber":611,"sourceCode":"        throw new UnsupportedOperationException(\n            \"Unsupported to derive Schema for type: \" + logicalType);\n    }\n  }\n\n  public static LogicalType extractValueTypeToAvroMap(LogicalType type) {\n    LogicalType keyType;\n    LogicalType valueType;\n    if (type instanceof MapType) {\n      MapType mapType = (MapType) type;\n      keyType = mapType.getKeyType();\n      valueType = mapType.getValueType();\n    } else {\n      MultisetType multisetType = (MultisetType) type;\n      keyType = multisetType.getElementType();\n      valueType = new IntType();\n    }\n    if (!keyType.is(LogicalTypeFamily.CHARACTER_STRING)) {\n      throw new UnsupportedOperationException(\n          \"Avro format doesn't support non-string as key type of map. \"\n              + \"The key type is: \"\n              + keyType.asSummaryString());\n    }\n    return valueType;\n  }\n\n  /** Returns schema with nullable true. */\n  private static Schema nullableSchema(Schema schema) {\n    return schema.isNullable()\n        ? schema\n        : Schema.createUnion(SchemaBuilder.builder().nullType(), schema);\n  }\n}\n","sourceCodeStart":593,"sourceCodeEnd":626,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/formats/avro/typeutils/AvroSchemaConverter.java#L593-L626","documentation":"extractValueTypeToAvroMap validates the key type of a Flink MAP/MULTISET before building the Avro map schema. Avro maps only allow string keys, so if the key type is not in the CHARACTER_STRING family the converter rejects it. Avro simply cannot represent non-string-keyed maps.","triggerScenarios":"Converting a Flink table schema containing MAP<INT, T>, MAP<BIGINT, T>, MULTISET<INT> (or any non-VARCHAR/CHAR key) to Avro via AvroSchemaConverter during Iceberg Avro write/serialization.","commonSituations":"Tables created from SQL with INTEGER-keyed maps or multisets; schemas ingested from sources like Kafka/Protobuf that use integer keys; converting a whole row schema that happens to include such a map.","solutions":["Change the map key type to VARCHAR/CHAR (string) in the table schema.","Restructure the data as an ARRAY<ROW<key,value>> instead of a non-string-keyed map.","Cast keys to STRING upstream in the Flink job before writing to the Iceberg table.","If only a MULTISET is intended, note MULTISET is supported by this method only for string element types; convert non-string multisets to MAP<STRING,INT> or arrays."],"exampleFix":"// before\nDataTypes.MAP(DataTypes.INT(), DataTypes.STRING())\n// after\nDataTypes.MAP(DataTypes.STRING(), DataTypes.STRING())","handlingStrategy":"validation","validationCode":"// Check map key types before conversion\nfor (Map.Entry<String, LogicalType> e : fieldTypes.entrySet()) {\n  if (e.getValue() instanceof MapType) {\n    LogicalType key = ((MapType) e.getValue()).getKeyType();\n    Preconditions.checkArgument(key.is(LogicalTypeFamily.CHARACTER_STRING),\n        \"Map key must be string: %s\", e.getKey());\n  }\n}","typeGuard":"boolean hasStringMapKeys(org.apache.flink.table.types.logical.LogicalType t) {\n  return !(t instanceof MapType)\n      || ((MapType) t).getKeyType().is(LogicalTypeFamily.CHARACTER_STRING);\n}","tryCatchPattern":null,"preventionTips":["Always define MAP columns with VARCHAR/CHAR keys in Flink DDL for Iceberg tables.","Model non-string-keyed associations as ARRAY<ROW<k,v>> instead of MAP.","Cast map keys to STRING upstream before writing."],"tags":["flink","avro","map-key-type","schema-conversion"],"backgroundTag":"incompatible-source-type","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}