{"record":{"id":"9867cd8966a47628","repo":"apache/beam","slug":"unhandled-logical-type-identifier","errorCode":null,"errorMessage":"Unhandled logical type ${identifier}","messagePattern":"Unhandled logical type (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java","lineNumber":1235,"sourceCode":"                  .addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT));\n        } else if (\"TIME\".equals(identifier)) {\n          baseType =\n              LogicalTypes.timeMillis()\n                  .addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT));\n        } else if (SqlTypes.TIMESTAMP.getIdentifier().equals(identifier)) {\n          baseType =\n              LogicalTypes.timestampMicros()\n                  .addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG));\n        } else if (Timestamp.IDENTIFIER.equals(identifier)) {\n          int precision = checkNotNull(logicalType.getArgument());\n          if (precision != 9) {\n            throw new RuntimeException(\n                \"Timestamp logical type precision not supported:\" + precision);\n          }\n          baseType = org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG);\n          baseType.addProp(\"logicalType\", TIMESTAMP_NANOS_LOGICAL_TYPE);\n        } else {\n          throw new RuntimeException(\n              \"Unhandled logical type \" + checkNotNull(fieldType.getLogicalType()).getIdentifier());\n        }\n        break;\n\n      case ARRAY:\n      case ITERABLE:\n        baseType =\n            org.apache.avro.Schema.createArray(\n                getFieldSchema(\n                    checkNotNull(fieldType.getCollectionElementType()), fieldName, namespace));\n        break;\n\n      case MAP:\n        if (checkNotNull(fieldType.getMapKeyType()).getTypeName().isStringType()) {\n          // Avro only supports string keys in maps.\n          baseType =\n              org.apache.avro.Schema.createMap(\n                  getFieldSchema(checkNotNull(fieldType.getMapValueType()), fieldName, namespace));","sourceCodeStart":1217,"sourceCodeEnd":1253,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java#L1217-L1253","documentation":"During Beam FieldType -> Avro schema conversion, the FieldType carries a logical type whose identifier is not handled by the converter (only Timestamp-related identifiers are supported in that switch). The library throws RuntimeException because it cannot map the logical type to any Avro representation.","triggerScenarios":"Calling AvroUtils.getFieldSchema/toAvroSchema with a FieldType whose getLogicalType() has an identifier other than the supported Timestamp variants (e.g. custom LogicalType implementations, Enumeration, FixedBytes-adjacent logical types depending on branch).","commonSituations":"Custom LogicalType subclasses registered on Beam schemas; schemas ported from other frameworks with unsupported logical annotations; upgrading Beam and passing logical types the Avro converter never implemented.","solutions":["Remove or replace the unsupported logical type on the FieldType before conversion.","Implement a mapping yourself by converting the field to its base type and attaching the Avro logical-type prop manually.","Register/extend the converter (or upstream a case for the identifier) if the logical type is broadly useful.","Catch RuntimeException around schema conversion and fall back to the field's underlying primitive type."],"exampleFix":"// before\nField.of(\"status\", FieldType.string().withLogicalType(new MyCustomLogicalType()))\n// after\nField.of(\"status\", FieldType.string()) // drop unsupported logical type before toAvroSchema","handlingStrategy":"validation","validationCode":"boolean hasSupportedLogicalType(FieldType ft) {\n  LogicalType lt = ft.getLogicalType();\n  return lt == null || SUPPORTED_IDENTIFIERS.contains(lt.getIdentifier()); // e.g. Timestamp variants only\n}","typeGuard":null,"tryCatchPattern":"try {\n  org.apache.avro.Schema s = AvroUtils.toAvroSchema(rowSchema);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Unhandled logical type \")) {\n    org.apache.avro.Schema s2 = AvroUtils.toAvroSchema(stripLogicalTypes(rowSchema));\n  } else { throw e; }\n}","preventionTips":["Avoid custom LogicalType implementations on fields destined for Avro sinks.","Strip or document unsupported logical types during schema ingestion.","Keep the Beam Avro extension up to date with the Beam SDK core.","Unit-test schema conversion for every production schema."],"tags":["avro","beam","logical-type","schema-conversion"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}