apache/beam · error · RuntimeException

Unsupported logical type " + logicalType.getIdentifier()

Error message

Unsupported logical type " + logicalType.getIdentifier()

What it means

BeamRowToStorageApiProto.scalarToProtoValue converts a Beam Row field value into a protobuf value for the BigQuery Storage Write API. For fields whose Beam type is a logical type, it looks up an encoder in the LOGICAL_TYPE_ENCODERS map by the LogicalType's identifier; if no encoder is registered for that identifier, it throws this RuntimeException.

Source

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

  @VisibleForTesting
  static Object scalarToProtoValue(
      @Nullable FieldDescriptor fieldDescriptor, FieldType beamFieldType, Object value) {
    if (beamFieldType.getTypeName() == TypeName.LOGICAL_TYPE) {
      @Nullable LogicalType<?, ?> logicalType = beamFieldType.getLogicalType();
      if (logicalType == null) {
        throw new RuntimeException("Unexpectedly null logical type " + beamFieldType);
      }
      if (logicalType.getIdentifier().equals(Timestamp.IDENTIFIER)) {
        Instant instant = (Instant) value;
        Descriptor timestampPicosDescriptor =
            Preconditions.checkNotNull(fieldDescriptor).getMessageType();
        return buildTimestampPicosMessage(timestampPicosDescriptor, instant);
      }
      @Nullable
      BiFunction<LogicalType<?, ?>, Object, Object> logicalTypeEncoder =
          LOGICAL_TYPE_ENCODERS.get(logicalType.getIdentifier());
      if (logicalTypeEncoder == null) {
        throw new RuntimeException("Unsupported logical type " + logicalType.getIdentifier());
      }
      return logicalTypeEncoder.apply(logicalType, value);
    } else {
      @Nullable
      Function<Object, Object> encoder = PRIMITIVE_ENCODERS.get(beamFieldType.getTypeName());
      if (encoder == null) {
        throw new RuntimeException("Unexpected beam type " + beamFieldType);
      }
      return encoder.apply(value);
    }
  }

  static Object mapEntryToProtoValue(
      Descriptor descriptor,
      FieldType keyFieldType,
      FieldType valueFieldType,
      Map.Entry<Object, Object> entryValue) {
    DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove or replace the custom LogicalType field with a primitive Beam type (STRING, LONG, etc.) the encoder supports
  2. Register an encoder in LOGICAL_TYPE_ENCODERS via its registration mechanism, mapping the identifier to a supported proto type
  3. Convert the logical-typed value to a supported type in a PTransform before the BigQuery sink
  4. Fall back to a non-Storage Write sink method (e.g. FILE_LOADS) that serializes rows differently

Example fix

// before
Schema.Field f = Schema.Field.of("id", Schema.FieldType.logicalType(new MyUuidType()));
// after
Schema.Field f = Schema.Field.of("id", Schema.FieldType.STRING); // convert UUID -> String in a MapElements
Defensive patterns

Strategy: validation

Validate before calling

Schema.FieldType ft = field.getType();
if (ft.getTypeName().equals(Schema.TypeName.LOGICAL_TYPE)) {
  String id = ft.getLogicalType().getIdentifier();
  if (!Set.of("Char", "UUID", "ISO-INSTANT").contains(id)) throw new IllegalArgumentException("No BigQuery encoder for logical type " + id);
}

Prevention

When it happens

Trigger: Calling toProtoValue on a Row whose Schema contains a field with a custom/unregistered LogicalType (e.g. a user-defined LogicalType or a standard logical type Beam does not map to BigQuery) while converting rows for the BigQuery Storage API sink.

Common situations: Users add a custom LogicalType to their schema (e.g. via Schema.builder().addLogicalTypeField) and then write to BigQuery with STORAGE_API/STORAGE_WRITE_API method; Beam has no built-in mapping for that identifier so serialization fails at runtime, typically in a DoFn during pipeline execution.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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