{"record":{"id":"9bd0bf94fac650de","repo":"apache/beam","slug":"local-timestamp-micros-can-only-be-used-with-an-underlying","errorCode":null,"errorMessage":"Local timestamp (micros) can only be used with an underlying long type","messagePattern":"Local timestamp \\(micros\\) can only be used with an underlying long type","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroJavaTimeConversions.java","lineNumber":66,"sourceCode":"    public void validate(Schema schema) {\n      super.validate(schema);\n      if (schema.getType() != Schema.Type.LONG) {\n        throw new IllegalArgumentException(\n            \"Local timestamp (millis) can only be used with an underlying long type\");\n      }\n    }\n  }\n\n  public static class LocalTimestampMicros extends LogicalType {\n    private LocalTimestampMicros() {\n      super(LOCAL_TIMESTAMP_MICROS);\n    }\n\n    @Override\n    public void validate(Schema schema) {\n      super.validate(schema);\n      if (schema.getType() != Schema.Type.LONG) {\n        throw new IllegalArgumentException(\n            \"Local timestamp (micros) can only be used with an underlying long type\");\n      }\n    }\n  }\n\n  public static class DateConversion extends Conversion<LocalDate> {\n\n    @Override\n    public Class<LocalDate> getConvertedType() {\n      return LocalDate.class;\n    }\n\n    @Override\n    public String getLogicalTypeName() {\n      return \"date\";\n    }\n\n    @Override","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroJavaTimeConversions.java#L48-L84","documentation":"AvroConverters' LocalTimestampMicrosConversion converts between Avro 'local-timestamp-micros' logical types and java.time.LocalDateTime. During schema validation it asserts the underlying Avro primitive type is LONG, since local-timestamp-micros is a logical type over a long (microseconds since epoch). If the schema declares a different physical type (e.g. int, string, record), validation fails immediately with this IllegalArgumentException.","triggerScenarios":"Calling Conversion.validate(schema) (directly or via Avro schema/Beam schema round-trip in AvroUtils) with a Schema whose getType() != Schema.Type.LONG while this conversion is registered for the local-timestamp-micros logical type.","commonSituations":"Hand-written Avro JSON/AVSC schemas where the field was declared as \"int\" or \"string\" instead of \"long\" with logicalType local-timestamp-micros; schema registry entries edited manually; older Avro versions or other producers writing timestamps as milliseconds-int that Beam consumers validate as micros-long.","solutions":["Change the Avro field's underlying type to long (e.g. {\"type\":\"long\",\"logicalType\":\"local-timestamp-micros\"}).","If millisecond precision suffices and the type is int, use the local-timestamp-millis logical type with its matching conversion instead.","If the field is not really a timestamp, drop the logicalType so the conversion is not applied.","Regenerate/update Java Avro classes or the schema string so the declared type matches the conversion."],"exampleFix":"// before (AVSC)\n{\"name\":\"eventTime\",\"type\":\"int\",\"logicalType\":\"local-timestamp-micros\"}\n// after\n{\"name\":\"eventTime\",\"type\":\"long\",\"logicalType\":\"local-timestamp-micros\"}","handlingStrategy":"validation","validationCode":"if (schema.getType() != org.apache.avro.Schema.Type.LONG) {\n  throw new IllegalArgumentException(\"field \" + schema.getName() + \" must be long for local-timestamp-micros\");\n}\nconversion.validate(schema); // safe\n","typeGuard":"boolean isLocalTsMicrosCompatible(org.apache.avro.Schema s) { return s.getType() == org.apache.avro.Schema.Type.LONG && \"local-timestamp-micros\".equals(s.getLogicalType() == null ? null : s.getLogicalType().getName()); }","tryCatchPattern":"try {\n  conversion.validate(schema);\n} catch (IllegalArgumentException e) {\n  throw new SchemaValidationException(\"Fix underlying Avro type to long: \" + schema, e);\n}","preventionTips":["Always define timestamp logical types over \"long\" in AVSC, never \"int\" or \"string\".","Validate schemas at build/startup time rather than at record-processing time.","Use Avro code generation from AVSC instead of hand-editing schema JSON.","Pin Avro library versions across producer and consumer."],"tags":["avro","schema","java","beam"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}