apache/beam · error · RuntimeException

Unknown logical type

Error message

Unknown logical type 

What it means

Same 'Unknown timestamp truncation option: %s' IllegalArgumentException as the DATETIME case, but thrown at BigQueryUtils.java:1066 for LOGICAL_TYPE fields whose identifier is in SQL_DATE_TIME_TYPES (e.g. SqlTimeWithLocalTzType). It means the truncation option passed into convertAvroFormat was neither TRUNCATE nor REJECT. Internal guard against an invalid enum value.

Solutions

  1. Pass BigQueryIO.withTruncatedTimestamps() or keep the default REJECT mode; never feed custom values into ConversionOptions.
  2. Align Beam SDK versions across all pipeline components.
  3. Rebuild/redeploy the pipeline with one consistent Beam release.
  4. In forked code, validate the enum before calling convertAvroFormat.

Example fix

// before
new ConversionOptions(myCustomMode) // unknown enum constant
// after
BigQueryIO.readTableRows().withTruncatedTimestamps() // TRUNCATE (or omit for REJECT)
Defensive patterns

Strategy: validation

Validate before calling

// Java: assert supported option before running a pipeline over SQL date-time logical types
switch (opts.getTruncateTimestamps()) {
  case TRUNCATE:
  case REJECT:
    break;
  default:
    throw new IllegalArgumentException("Unsupported truncateTimestamps: " + opts.getTruncateTimestamps());
}

Try / catch

try { convert(...) } catch (IllegalArgumentException e) { if (e.getMessage().contains("Unknown timestamp truncation option")) { opts = ConversionOptions.truncateTimestamps(); convert(...); } else throw e; }

Prevention

When it happens

Trigger: Reading BigQuery data containing a SQL date-time logical type (e.g. SqlTimeWithLocalTzType) via the Avro path while ConversionOptions.getTruncateTimestamps() holds an unknown value (not TRUNCATE/REJECT).

Common situations: Version-skew between Beam SDKs producing/consuming the enum; custom ConversionOptions instances; forked BigQueryIO code with an extended enum.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

        return convertAvroArray(beamFieldType, avroValue, options);
      case LOGICAL_TYPE:
        LogicalType<?, ?> logicalType =
            Preconditions.checkArgumentNotNull(beamFieldType.getLogicalType());
        String identifier = logicalType.getIdentifier();
        if (SqlTypes.DATE.getIdentifier().equals(identifier)) {
          return convertAvroDate(avroValue);
        } else if (SqlTypes.TIME.getIdentifier().equals(identifier)) {
          return convertAvroTime(avroValue);
        } else if (SqlTypes.DATETIME.getIdentifier().equals(identifier)) {
          return convertAvroDateTime(avroValue);
        } else if (SQL_DATE_TIME_TYPES.contains(identifier)) {
          switch (options.getTruncateTimestamps()) {
            case TRUNCATE:
              return truncateToMillis(avroValue);
            case REJECT:
              return safeToMillis(avroValue);
            default:
              throw new IllegalArgumentException(
                  String.format(
                      "Unknown timestamp truncation option: %s", options.getTruncateTimestamps()));
          }
        } else if (logicalType instanceof PassThroughLogicalType) {
          return convertAvroFormat(logicalType.getBaseType(), avroValue, options);
        } else {
          throw new RuntimeException("Unknown logical type " + identifier);
        }
      case ROW:
        Schema rowSchema = beamFieldType.getRowSchema();
        if (rowSchema == null) {
          throw new IllegalArgumentException("Nested ROW missing row schema");
        }
        GenericData.Record record = (GenericData.Record) avroValue;
        return toBeamRow(record, rowSchema, options);
      case MAP:
        return convertAvroRecordToMap(beamFieldType, avroValue, options);
      default:

View on GitHub (pinned to 12126d8942)