apache/beam · error · IllegalArgumentException

Local timestamp (micros) can only be used with an underlying

Error message

Local timestamp (micros) can only be used with an underlying long type

What it means

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.

Source

Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroJavaTimeConversions.java:66

    public void validate(Schema schema) {
      super.validate(schema);
      if (schema.getType() != Schema.Type.LONG) {
        throw new IllegalArgumentException(
            "Local timestamp (millis) can only be used with an underlying long type");
      }
    }
  }

  public static class LocalTimestampMicros extends LogicalType {
    private LocalTimestampMicros() {
      super(LOCAL_TIMESTAMP_MICROS);
    }

    @Override
    public void validate(Schema schema) {
      super.validate(schema);
      if (schema.getType() != Schema.Type.LONG) {
        throw new IllegalArgumentException(
            "Local timestamp (micros) can only be used with an underlying long type");
      }
    }
  }

  public static class DateConversion extends Conversion<LocalDate> {

    @Override
    public Class<LocalDate> getConvertedType() {
      return LocalDate.class;
    }

    @Override
    public String getLogicalTypeName() {
      return "date";
    }

    @Override

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the Avro field's underlying type to long (e.g. {"type":"long","logicalType":"local-timestamp-micros"}).
  2. If millisecond precision suffices and the type is int, use the local-timestamp-millis logical type with its matching conversion instead.
  3. If the field is not really a timestamp, drop the logicalType so the conversion is not applied.
  4. Regenerate/update Java Avro classes or the schema string so the declared type matches the conversion.

Example fix

// before (AVSC)
{"name":"eventTime","type":"int","logicalType":"local-timestamp-micros"}
// after
{"name":"eventTime","type":"long","logicalType":"local-timestamp-micros"}
Defensive patterns

Strategy: validation

Validate before calling

if (schema.getType() != org.apache.avro.Schema.Type.LONG) {
  throw new IllegalArgumentException("field " + schema.getName() + " must be long for local-timestamp-micros");
}
conversion.validate(schema); // safe

Type guard

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()); }

Try / catch

try {
  conversion.validate(schema);
} catch (IllegalArgumentException e) {
  throw new SchemaValidationException("Fix underlying Avro type to long: " + schema, e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/9bd0bf94fac650de. Report an issue: GitHub.