apache/beam · error · IllegalStateException

Unable to construct %s counter for PTransform {id=%s, name=%

Error message

Unable to construct %s counter for PTransform {id=%s, name=%s}

What it means

After building a MonitoringInfo for the execution state (URN + SUM_INT64 type + PTRANSFORM label), SimpleMonitoringInfoBuilder.build() returned null, indicating the monitoring info was incomplete/invalid (e.g. the URN is not recognized as a valid execution state counter). The registry throws IllegalStateException naming the URN and PTransform it could not instrument.

Source

Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/data/PTransformFunctionRegistry.java:103

    this.stateTracker = stateTracker;
  }

  /**
   * Register the runnable to process the specific pTransformId and track its execution time.
   *
   * @param pTransformId
   * @param pTransformUniqueName
   * @param runnable
   */
  public void register(
      String pTransformId, String pTransformUniqueName, ThrowingRunnable runnable) {
    SimpleMonitoringInfoBuilder miBuilder = new SimpleMonitoringInfoBuilder();
    miBuilder.setUrn(executionStateUrn);
    miBuilder.setType(MonitoringInfoConstants.TypeUrns.SUM_INT64_TYPE);
    miBuilder.setLabel(MonitoringInfoConstants.Labels.PTRANSFORM, pTransformId);
    MonitoringInfo mi = miBuilder.build();
    if (mi == null) {
      throw new IllegalStateException(
          String.format(
              "Unable to construct %s counter for PTransform {id=%s, name=%s}",
              executionStateUrn, pTransformId, pTransformUniqueName));
    }
    String shortId = shortIds.getOrCreateShortId(mi);
    ExecutionState executionState =
        stateTracker.create(shortId, pTransformId, pTransformUniqueName, stateName);

    ThrowingRunnable wrapped =
        () -> {
          try (ExecutionState.ActiveState ignored = executionState.scopedActivate()) {
            runnable.run();
          }
        };
    runnables.add(wrapped);
  }

  /**

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the executionStateUrn passed to register() is a valid execution-state Urns constant and non-null.
  2. Log/inspect the constructed MonitoringInfo (miBuilder) to see which validation failed.
  3. Update URN constants after Beam SDK upgrades.
  4. Add a unit test exercising register() with the URNs used by your runner.

Example fix

// before
registry.register(pTransformId, pTransformName, fn, "process_bad_urn");
// after
registry.register(pTransformId, pTransformName, fn, MonitoringInfoConstants.Urns.PROCESS_BUNDLE_MSECS);
Defensive patterns

Strategy: validation

Validate before calling

SimpleMonitoringInfoBuilder b = new SimpleMonitoringInfoBuilder(); b.setUrn(urn); b.setType(MonitoringInfoConstants.TypeUrns.SUM_INT64_TYPE); b.setLabel(MonitoringInfoConstants.Labels.PTRANSFORM, id); if (b.build() == null) throw new IllegalStateException("URN not constructible: " + urn);

Try / catch

try { registry.register(id, name, fn, urn); } catch (IllegalStateException e) { LOG.error("Counter construction failed for {}", urn, e); throw e; }

Prevention

When it happens

Trigger: register(...) is called with an executionStateUrn that SimpleMonitoringInfoBuilder cannot turn into a valid counter — commonly because the URN is empty or not a valid execution-state URN, so miBuilder.build() yields null.

Common situations: Custom runner passes an unsupported/wrong URN string; constants changed across Beam versions; URN left null during registry construction in tests.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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