apache/beam · error · IllegalArgumentException

Cannot set both version and timestamp.

Error message

Cannot set both version and timestamp.

What it means

DeltaTable rejects specifying both a 'version' and a 'timestamp' property, since a Delta table snapshot can be resolved by exactly one of the two time-travel selectors, not both. The check is a mutually-exclusive-options guard in the constructor/property validation.

Source

Thrown at sdks/java/extensions/sql/delta/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/delta/DeltaTable.java:103

                "Beam write property '%s' is not supported. Writing to Delta Lake tables is currently not supported.",
                key));
      } else if (lowerKey.startsWith(BEAM_READ_PROPERTY)) {
        // none supported yet
        throw new IllegalArgumentException("Unknown Beam read property: " + key);
      } else if (lowerKey.equalsIgnoreCase(VERSION_FIELD)) {
        parsedVersion = parseVersion(val);
      } else if (lowerKey.equalsIgnoreCase(TIMESTAMP_FIELD)) {
        parsedTimestamp = val.asText();
      } else if (lowerKey.equalsIgnoreCase(HADOOP_CONFIG_FIELD)
          || lowerKey.equalsIgnoreCase(HADOOP_CONFIG_CAMEL_FIELD)) {
        parseHadoopConfig(val, parsedHadoopConfig);
      } else {
        throw new IllegalArgumentException(String.format("Unknown property '%s'", key));
      }
    }

    if (parsedVersion != null && parsedTimestamp != null) {
      throw new IllegalArgumentException("Cannot set both version and timestamp.");
    }

    this.version = parsedVersion;
    this.timestamp = parsedTimestamp;
    this.hadoopConfig = parsedHadoopConfig.isEmpty() ? null : parsedHadoopConfig;
  }

  private static Long parseVersion(JsonNode val) {
    if (val.isNumber()) {
      return val.asLong();
    }
    return Long.parseLong(val.asText());
  }

  private static void parseHadoopConfig(JsonNode val, Map<String, String> targetMap) {
    if (val.isObject()) {
      Map<String, String> map =
          TableUtils.getObjectMapper()

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove either the 'version' or the 'timestamp' property, keeping only one.
  2. Decide the snapshot-selection strategy (time travel by version OR by timestamp) and configure accordingly.

Example fix

// before
TBLPROPERTIES { 'version': '5', 'timestamp': '"2024-01-01T00:00:00Z"' }
// after
TBLPROPERTIES { 'version': '5' }
Defensive patterns

Strategy: validation

Validate before calling

if (properties.containsKey("version") && properties.containsKey("timestamp")) {
  throw new IllegalArgumentException("Specify only one of 'version' or 'timestamp' for Delta time travel");
}

Try / catch

try {
  table = new DeltaTable(tableId, schema, properties);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("both version and timestamp")) {
    properties.remove("timestamp"); // keep version-based time travel
  }
}

Prevention

When it happens

Trigger: Creating a DeltaTable whose properties include both a non-null parsed version and a non-null parsed timestamp.

Common situations: Merging property maps from multiple config sources so both keys end up present; template defaults including 'timestamp' while the user also sets 'version'.

Related errors


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