apache/beam · error · NullPointerException
Time unit cannot be null when MAX_STALENESS or EXACT_STALENE
Error message
Time unit cannot be null when MAX_STALENESS or EXACT_STALENESS mode is selected
What it means
getTimestampBound() requires a TimeUnit whenever the Spanner read mode is MAX_STALENESS or EXACT_STALENESS; the staleness number alone is not a duration. This NullPointerException is thrown when timeUnit is null, because TimestampBound.ofMaxStaleness/ofExactStaleness needs (long, TimeUnit).
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java:202
this.staleness = staleness;
}
private @Nullable TimestampBound getTimestampBound() {
if (timestampBoundMode == null) {
return null;
}
TimestampBound.Mode mode = TimestampBound.Mode.valueOf(timestampBoundMode);
switch (mode) {
case STRONG:
return TimestampBound.strong();
case MAX_STALENESS:
case EXACT_STALENESS:
if (staleness == null) {
throw new NullPointerException(
"Staleness value cannot be empty when MAX_STALENESS or EXACT_STALENESS mode is selected");
}
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);
}
}View on GitHub (pinned to 12126d8942)
Solutions
- Call .withTimeUnit("SECONDS") (or another valid java.util.concurrent.TimeUnit name) alongside the staleness value.
- Verify the unit string is a valid TimeUnit enum constant (NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS).
- Use STRONG mode if you don't need bounded staleness.
Example fix
// before
.withTimestampBoundMode("EXACT_STALENESS").withStaleness(15)
// after
.withTimestampBoundMode("EXACT_STALENESS").withStaleness(15).withTimeUnit("SECONDS") Defensive patterns
Strategy: validation
Validate before calling
if ((mode == TimestampBoundMode.MAX_STALENESS || mode == TimestampBoundMode.EXACT_STALENESS) && timeUnit == null) { throw new IllegalArgumentException(mode + " requires a TimeUnit"); } Try / catch
try { TimeUnit u = TimeUnit.valueOf(config.getTimeUnit()); } catch (NullPointerException | IllegalArgumentException e) { throw new ConfigException("Invalid or missing timeUnit: " + config.getTimeUnit(), e); } Prevention
- Parse the unit with TimeUnit.valueOf up front and fail with a clear message on bad input.
- Pair staleness and unit in one setter/helper so they cannot diverge.
- List accepted unit names in your config schema documentation.
When it happens
Trigger: Setting mode MAX_STALENESS or EXACT_STALENESS with a staleness value but no time unit (withTimeUnit not called, or the timeUnit field missing/blank in external configuration).
Common situations: Config files where staleness was added as "10" but the unit key was forgotten; programmatic builders copying another mode's setup; invalid unit strings would also fail later at TimeUnit.valueOf, so ensure exact JDK unit names.
Related errors
- Staleness value cannot be empty when MAX_STALENESS or EXACT_
- Timestamp cannot be null when READ_TIMESTAMP or MIN_READ_TIM
- lenientFormat(errorMessageTemplate, p1, p2)
- Can't compare %s with NULL
- databaseId can't be empty
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/7d43a466972e1f6e.
Report an issue: GitHub.