apache/beam · error · IllegalArgumentException

Unsupported logical type " + logicalType.getName()

Error message

Unsupported logical type " + logicalType.getName()

What it means

scalarToProtoValue looks up an encoder for a field's Avro logical type in LOGICAL_TYPE_ENCODERS. If a logical type is present but has no registered encoder (e.g. unknown or custom named logical types like "decimal-metadata" or user-defined logical types), it throws IllegalArgumentException("Unsupported logical type ..."). Only a fixed set of logical types (timestamp, date, time, decimal) is supported.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/AvroGenericRecordToStorageApiProto.java:569

      // Handle negative timestamps (before epoch)
      if (nanos < 0 && nanoAdjustment != 0) {
        seconds -= 1;
        nanoAdjustment += NANOS_PER_SECOND;
      }

      long picoseconds = nanoAdjustment * PICOS_PER_NANO;
      return buildTimestampPicosMessage(
          Preconditions.checkNotNull(descriptor).getMessageType(), seconds, picoseconds);
    }
    LogicalType logicalType = LogicalTypes.fromSchema(type.getType());

    if (logicalType != null) {
      @Nullable
      BiFunction<LogicalType, Object, Object> logicalTypeEncoder =
          LOGICAL_TYPE_ENCODERS.get(logicalType.getName());
      if (logicalTypeEncoder == null) {
        throw new IllegalArgumentException("Unsupported logical type " + logicalType.getName());
      }
      return logicalTypeEncoder.apply(logicalType, value);
    } else {
      @Nullable Function<Object, Object> encoder = PRIMITIVE_ENCODERS.get(type.getType().getType());
      if (encoder == null) {
        throw new RuntimeException("Unexpected beam type " + fieldSchema);
      }
      return encoder.apply(value);
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove or flatten the unsupported logical type from the Avro schema (use the underlying primitive type)
  2. Pre-convert the value to a supported type (e.g. convert custom logical types to long/string) before writing
  3. Check the supported encoder keys in AvroGenericRecordToStorageApiProto.LOGICAL_TYPE_ENCODERS and match your logical type name to one
  4. Upgrade Beam — newer versions add support for more logical types

Example fix

// before
Schema uuidField = LogicalTypes.uuid().addToSchema(Schema.create(Schema.Type.STRING));
// after
Schema uuidField = Schema.create(Schema.Type.STRING); // plain string
Defensive patterns

Strategy: validation

Validate before calling

// Java
Schema logicalTypeSchema = schema.getField(name).schema();
LogicalType lt = logicalTypeSchema.getLogicalType();
if (lt != null && !Set.of("timestamp-millis","timestamp-micros","date","time-millis","time-micros","decimal").contains(lt.getName())) {
  throw new IllegalStateException("Unsupported logical type: " + lt.getName());
}

Type guard

// Java
BiFunction<LogicalType, Object, Object> enc = LOGICAL_TYPE_ENCODERS.get(lt.getName());
if (enc != null) { /* supported */ }

Try / catch

// Java
try {
  return scalarToProtoValue(fieldSchema, type, value);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Unsupported logical type")) {
    // fall back to primitive conversion or skip field
  }
  throw e;
}

Prevention

When it happens

Trigger: Writing Avro GenericRecords with a field whose schema has a logicalType not in LOGICAL_TYPE_ENCODERS (e.g. custom logical types, uuid, duration) to BigQuery via Storage API

Common situations: Avro schemas generated by tools that attach custom logical types (Confluent schema registry, Avro 1.9+ logical types like uuid), or decimal logical types with unsupported precision/scale combos.

Related errors


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