{"record":{"id":"dd3cbdedcdb03998","repo":"apache/iceberg","slug":"unsupported-logical-type-logicaltype","errorCode":null,"errorMessage":"Unsupported logical type: ${logicalType}","messagePattern":"Unsupported logical type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkAvroWriter.java","lineNumber":138,"sourceCode":"\n          case \"time-micros\":\n            return FlinkValueWriters.timeMicros();\n\n          case \"timestamp-micros\":\n            return FlinkValueWriters.timestampMicros();\n\n          case \"timestamp-nanos\":\n            return FlinkValueWriters.timestampNanos();\n\n          case \"decimal\":\n            LogicalTypes.Decimal decimal = (LogicalTypes.Decimal) logicalType;\n            return FlinkValueWriters.decimal(decimal.getPrecision(), decimal.getScale());\n\n          case \"uuid\":\n            return FlinkValueWriters.uuids();\n\n          default:\n            throw new IllegalArgumentException(\"Unsupported logical type: \" + logicalType);\n        }\n      }\n\n      switch (primitive.getType()) {\n        case NULL:\n          return ValueWriters.nulls();\n        case BOOLEAN:\n          return ValueWriters.booleans();\n        case INT:\n          switch (type.getTypeRoot()) {\n            case TINYINT:\n              return ValueWriters.tinyints();\n            case SMALLINT:\n              return ValueWriters.shorts();\n            default:\n              return ValueWriters.ints();\n          }\n        case LONG:","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkAvroWriter.java#L120-L156","documentation":"FlinkAvroWriter converts Flink data to Avro values for Iceberg Avro file writing. Logical type mapping only handles a fixed set (string, date/time, timestamps, decimal, uuid); any other Avro logical type hits the default case and throws IllegalArgumentException 'Unsupported logical type'.","triggerScenarios":"Writing Avro files for an Iceberg table whose Avro schema carries a logical type outside the supported set.","commonSituations":"Schemas produced by tools adding custom Avro logical types; hand-edited Avro schemas; ingesting foreign data with exotic logical types into an Iceberg Avro write path.","solutions":["Remove or map the unsupported Avro logical type to a plain primitive in the writer schema","Register support for the logical type by extending the writer switch (upstream change)","Convert the column to a supported type before writing (e.g. store UUID as string if the logical type is not recognized)"],"exampleFix":"// before\nAvro schema field with logicalType \"custom-id\" -> throws\n// after\nfield.type() = string with no logicalType (or use the \"uuid\" logical type)","handlingStrategy":"validation","validationCode":"LogicalType lt = field.schema().getLogicalType(); if (lt != null && !SUPPORTED_LOGICAL.contains(lt.getName())) throw new IllegalArgumentException(\"unsupported logical type \" + lt);","typeGuard":"boolean supportedLogical(Schema s) { String n = s.getLogicalType() == null ? null : s.getLogicalType().getName(); return n == null || Set.of(\"string\",\"date\",\"time-millis\",\"time-micros\",\"timestamp-millis\",\"timestamp-micros\",\"decimal\",\"uuid\").contains(n); }","tryCatchPattern":"try { writer.write(row); } catch (IllegalArgumentException e) { LOG.error(\"Avro write failed: {}\", e.getMessage()); throw e; }","preventionTips":["Keep Avro writer schemas tool-generated and standard","Avoid custom logical types in table schemas","Test schema round-trips before production writes"],"tags":["flink","avro","schema"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}