apache/beam · error · UnsupportedOperationException

Timestamp unsupported in ${context}

Error message

Timestamp unsupported in ${context}

What it means

This UnsupportedOperationException is thrown by DoFnInvoker.BaseArgumentProvider.timestamp when the element timestamp parameter is requested in a DoFn invocation context that has no input element. Only @ProcessElement (and similar element-processing contexts) carries a bounded input with a timestamp; contexts like @StartBundle or @FinishBundle leave timestamp un-overridden in the base provider, which always throws. getErrorContext() identifies the offending context in the message.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java:342

      throw new UnsupportedOperationException(
          String.format("SideInput unsupported in %s", getErrorContext()));
    }

    @Override
    public TimerMap timerFamily(String tagId) {
      throw new UnsupportedOperationException(
          String.format("TimerFamily unsupported in %s", getErrorContext()));
    }

    @Override
    public @Nullable Object schemaElement(int index) {
      throw new UnsupportedOperationException(
          String.format("Schema element unsupported in %s", getErrorContext()));
    }

    @Override
    public Instant timestamp(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("Timestamp unsupported in %s", getErrorContext()));
    }

    @Override
    public @Nullable String currentRecordId(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("RecordId unsupported in %s", getErrorContext()));
    }

    @Override
    public @Nullable Long currentRecordOffset(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(
          String.format("RecordOffset unsupported in %s", getErrorContext()));
    }

    @Override
    public Instant fireTimestamp(DoFn<InputT, OutputT> doFn) {
      throw new UnsupportedOperationException(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Request the timestamp parameter only in @ProcessElement; capture or aggregate timestamps into instance fields if they are needed later in @FinishBundle.
  2. In @OnTimer methods, use the fireTimestamp parameter (Instant of the timer firing) rather than the element timestamp.
  3. Remove the timestamp parameter from lifecycle methods entirely if no per-element value is meaningful there.
  4. If implementing a custom ArgumentProvider, override timestamp(DoFn) to return the current element's timestamp.

Example fix

// before
@FinishBundle
public void finishBundle(FinishBundleContext c, Instant ts) { // throws
  c.output(buildResult(), ts, window);
}

// after
private Instant lastTs;

@ProcessElement
public void processElement(ProcessContext c, Instant ts) {
  lastTs = ts;
}

@FinishBundle
public void finishBundle(FinishBundleContext c) {
  c.output(buildResult(), lastTs, window);
}
Defensive patterns

Strategy: validation

Validate before calling

// Element timestamp exists only in element-processing context; verify the method annotation.
// Before adding an 'Instant ts' parameter, confirm the method is @ProcessElement (or use fireTimestamp in @OnTimer).

Type guard

if (context instanceof DoFn.ProcessContext) {
  Instant ts = context.timestamp();
}

Try / catch

try {
  Instant ts = context.timestamp();
} catch (UnsupportedOperationException e) {
  // no element in this phase; use a stored timestamp or Instant.now()-based policy
}

Prevention

When it happens

Trigger: Declaring an Instant timestamp parameter (or calling c.timestamp(doFn) / BoundedWindow-style accessors relying on it) in @StartBundle, @FinishBundle, @OnTimer (use fireTimestamp there), @OnWindowExpiration methods, or a custom ArgumentProvider that does not override timestamp(DoFn).

Common situations: Copy-pasting a @ProcessElement signature including the timestamp parameter into a @FinishBundle aggregation method; expecting to read the last element's timestamp in @FinishBundle; test harness ArgumentProviders that only override element() and outputReceiver().

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