{"record":{"id":"22ba8595b1925012","repo":"apache/iceberg","slug":"unknown-logical-type-logicaltype-22ba85","errorCode":null,"errorMessage":"Unknown logical type: {logicalType}","messagePattern":"Unknown logical type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/data/SparkPlannedAvroReader.java","lineNumber":162,"sourceCode":"          case \"timestamp-millis\":\n            // adjust to microseconds\n            ValueReader<Long> longs = ValueReaders.longs();\n            return (ValueReader<Long>) (decoder, ignored) -> longs.read(decoder, null) * 1000L;\n\n          case \"timestamp-micros\":\n            // Spark uses the same representation\n            return ValueReaders.longs();\n\n          case \"decimal\":\n            return SparkValueReaders.decimal(\n                ValueReaders.decimalBytesReader(primitive),\n                ((LogicalTypes.Decimal) logicalType).getScale());\n\n          case \"uuid\":\n            return SparkValueReaders.uuids();\n\n          default:\n            throw new IllegalArgumentException(\"Unknown logical type: \" + logicalType);\n        }\n      }\n\n      switch (primitive.getType()) {\n        case NULL:\n          return ValueReaders.nulls();\n        case BOOLEAN:\n          return ValueReaders.booleans();\n        case INT:\n          if (partner != null && partner.typeId() == Type.TypeID.LONG) {\n            return ValueReaders.intsAsLongs();\n          }\n          return ValueReaders.ints();\n        case LONG:\n          return ValueReaders.longs();\n        case FLOAT:\n          if (partner != null && partner.typeId() == Type.TypeID.DOUBLE) {\n            return ValueReaders.floatsAsDoubles();","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/data/SparkPlannedAvroReader.java#L144-L180","documentation":"SparkPlannedAvroReader.primitive handles Avro logical types (decimal, uuid, date, timestamp-millis/micros). An Avro schema carrying a logical type outside that set (e.g. time-millis, duration) reaches the default branch and throws IllegalArgumentException.","triggerScenarios":"Planning an Avro read where a field's schema has getLogicalType() returning an unknown logical type name, e.g. Avro 'duration' or custom logical types.","commonSituations":"Reading Avro files written with newer Avro logical types or vendor-specific logical types unsupported by this Iceberg version.","solutions":["Remove or convert unsupported logical types in the Avro schema (read the field as its underlying primitive).","Upgrade Iceberg to a version whose Avro reader supports the logical type.","Re-encode the data with standard logical types (e.g. timestamp-micros, decimal)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// inspect Avro schema logical types before planning\nfor (Schema.Field f : avroSchema.getFields()) {\n  LogicalType lt = f.schema().getLogicalType();\n  Preconditions.checkArgument(\n      lt == null || Set.of(\"decimal\",\"uuid\",\"date\",\"timestamp-millis\",\"timestamp-micros\")\n          .contains(lt.getName()),\n      \"Unsupported Avro logical type: %s\", lt);}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stick to core Avro logical types when producing data for Iceberg reads","Re-encode files with custom/vendor logical types","Upgrade Iceberg for newer standard logical types"],"tags":["spark","avro","logical-type","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-14T21:17:11.552Z"}