{"record":{"id":"749ec0a66b5dee13","repo":"apache/iceberg","slug":"cannot-parse-type-from-json","errorCode":null,"errorMessage":"Cannot parse type from json: ","messagePattern":"Cannot parse type from json: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SchemaParser.java","lineNumber":195,"sourceCode":"\n  private static Type typeFromJson(JsonNode json) {\n    if (json.isTextual()) {\n      return Types.fromTypeName(json.asText());\n    } else if (json.isObject()) {\n      JsonNode typeObj = json.get(TYPE);\n      if (typeObj != null) {\n        String type = typeObj.asText();\n        if (STRUCT.equals(type)) {\n          return structFromJson(json);\n        } else if (LIST.equals(type)) {\n          return listFromJson(json);\n        } else if (MAP.equals(type)) {\n          return mapFromJson(json);\n        }\n      }\n    }\n\n    throw new IllegalArgumentException(\"Cannot parse type from json: \" + json);\n  }\n\n  private static Literal<?> defaultFromJson(String defaultField, Type type, JsonNode json) {\n    if (json.has(defaultField)) {\n      Object value = SingleValueParser.fromJson(type, json.get(defaultField));\n      if (type instanceof Types.TimestampNanoType) {\n        // Call Expressions.nanos instead of Expressions.lit to prevent overflow\n        // https://github.com/apache/iceberg/issues/13160\n        return Expressions.nanos((long) value);\n      }\n\n      return Expressions.lit(value);\n    }\n\n    return null;\n  }\n\n  private static Types.NestedField.Builder fieldBuilder(boolean isRequired, String name) {","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SchemaParser.java#L177-L213","documentation":"SchemaParser.typeFromJson(JsonNode) parses a JSON node into an Iceberg Type by matching the 'type' string against known primitive names and complex-type markers (struct/list/map). If the node does not match any known type form, it throws this IllegalArgumentException. It rejects malformed or forward-incompatible type JSON during schema deserialization.","triggerScenarios":"SchemaParser.fromJson(json) on JSON with an unrecognized 'type' value (typo like 'timestamptz' variants unsupported in that version, 'unknown', empty string), a non-string/non-object type node, or a type name introduced in a newer Iceberg spec version.","commonSituations":"Schema JSON produced by a newer Iceberg (e.g. unknown/nano types) parsed by an older client; hand-written schema JSON with typos; other frameworks emitting non-Iceberg type descriptors into Iceberg parsers.","solutions":["Verify the 'type' value matches an Iceberg type name exactly (boolean, int, long, float, double, decimal(p,s), date, time, timestamp, timestamptz, string, uuid, fixed(n), binary, or object with type: struct/list/map)","Upgrade Iceberg on the reading side if the type was written by a newer version","Fix typos and remove whitespace; matching is exact, not case-insensitive"],"exampleFix":"// before\n{\"type\": \"Timestamp\"} // wrong casing/format\n// after\n{\"type\": \"timestamp\"} // or \"timestamptz\" for timestamp with zone","handlingStrategy":"validation","validationCode":"JsonNode typeNode = json.get(\"type\");\nSet<String> primitives = Set.of(\"boolean\",\"int\",\"long\",\"float\",\"double\",\"date\",\"time\",\"timestamp\",\"timestamptz\",\"string\",\"uuid\",\"binary\");\nboolean ok = typeNode != null && (primitives.contains(typeNode.asText()) || typeNode.asText().startsWith(\"decimal\") || typeNode.asText().startsWith(\"fixed\") || Set.of(\"struct\",\"list\",\"map\").contains(typeNode.asText()));\nif (!ok) throw new IllegalArgumentException(\"Unknown Iceberg type: \" + typeNode);","typeGuard":"static boolean isKnownTypeJson(JsonNode node) {\n  if (node == null || node.get(\"type\") == null) return false;\n  String t = node.get(\"type\").asText();\n  return t.equals(\"struct\") || t.equals(\"list\") || t.equals(\"map\") || t.matches(\"(decimal|fixed)\\\\(.*\\\\)\") || Set.of(\"boolean\",\"int\",\"long\",\"float\",\"double\",\"date\",\"time\",\"timestamp\",\"timestamptz\",\"string\",\"uuid\",\"binary\").contains(t);\n}","tryCatchPattern":"try {\n  return SchemaParser.fromJson(json);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Cannot parse type\")) throw new SchemaParseException(\"Unsupported type in schema JSON: \" + e.getMessage(), e);\n  throw e;\n}","preventionTips":["Match type names exactly as defined by the Iceberg spec (lowercase, no spaces)","Upgrade the reading client when schema JSON comes from a newer Iceberg writer","Validate externally produced type descriptors against the Iceberg spec before parsing"],"tags":["json","deserialization","schema"],"backgroundTag":"schema-validation-failed","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"}