apache/beam · error · IllegalArgumentException

Unknown timestamp bound mode: + mode

Error message

Unknown timestamp bound mode: + mode

What it means

getTimestampBound() switches over the configured timestamp bound mode and falls through to a default branch that throws IllegalArgumentException("Unknown timestamp bound mode: " + mode) when the mode string/value does not match any known enum constant (STRONG, MAX_STALENESS, EXACT_STALENESS, READ_TIMESTAMP, MIN_READ_TIMESTAMP). It means the mode supplied to the Spanner read configuration is not recognized.

Solutions

  1. Use exactly one of: STRONG, MAX_STALENESS, EXACT_STALENESS, READ_TIMESTAMP, MIN_READ_TIMESTAMP (enum name, uppercase).
  2. Validate the mode against TimestampBoundMode.valueOf(mode) in a try/catch before building.
  3. If the value comes from config, log the raw value and compare against the enum's allowed values.

Example fix

// before
.withTimestampBoundMode("max_staleness")
// after
.withTimestampBoundMode("MAX_STALENESS")
Defensive patterns

Strategy: validation

Validate before calling

try { TimestampBoundMode.valueOf(modeStr); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("mode must be one of STRONG, MAX_STALENESS, EXACT_STALENESS, READ_TIMESTAMP, MIN_READ_TIMESTAMP, got: " + modeStr); }

Try / catch

try { config.timestampBound(); } catch (IllegalArgumentException e) { log.error("Bad timestamp bound mode: {}", e.getMessage()); throw new ConfigException(e); }

Prevention

When it happens

Trigger: Passing a mode string that is not a valid enum name — wrong casing ("strong"), misspelling ("MAX_STALENSS"), a numeric/ordinal value instead of a name, or an externally-supplied mode value outside the enum set.

Common situations: Pipeline spec JSON/YAML written by hand or generated by another tool using different mode vocabulary; version drift where a mode was renamed; languages/dialects that lowercase enum names in serialization.

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/871206f26f124932. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java:218

            }
            if (timeUnit == null) {
              throw new NullPointerException(
                  "Time unit cannot be null when MAX_STALENESS or EXACT_STALENESS mode is selected");
            }
            return mode == MAX_STALENESS
                ? TimestampBound.ofMaxStaleness(staleness, TimeUnit.valueOf(timeUnit))
                : TimestampBound.ofExactStaleness(staleness, TimeUnit.valueOf(timeUnit));
          case READ_TIMESTAMP:
          case MIN_READ_TIMESTAMP:
            if (readTimestamp == null) {
              throw new NullPointerException(
                  "Timestamp cannot be null when READ_TIMESTAMP or MIN_READ_TIMESTAMP mode is selected");
            }
            return mode == READ_TIMESTAMP
                ? TimestampBound.ofReadTimestamp(Timestamp.parseTimestamp(readTimestamp))
                : TimestampBound.ofMinReadTimestamp(Timestamp.parseTimestamp(readTimestamp));
          default:
            throw new IllegalArgumentException("Unknown timestamp bound mode: " + mode);
        }
      }

      public ReadOperation getReadOperation() {
        if (sql != null && table != null) {
          throw new IllegalStateException(
              "Query and table params are mutually exclusive. Set just one of them.");
        }
        ReadOperation readOperation = ReadOperation.create();
        if (sql != null) {
          return readOperation.withQuery(sql);
        }
        if (Schema.builder().build().equals(schema)) {
          throw new IllegalArgumentException("Schema can't be empty");
        }
        if (table != null) {
          return readOperation.withTable(table).withColumns(schema.getFieldNames());
        }

View on GitHub (pinned to 12126d8942)