apache/beam · error · ValueError

Metric namespace must be non-empty

Error message

Metric namespace must be non-empty

What it means

apache_beam.metrics.metricbase.Metric's __init__ raises ValueError when a MonitoringInfo URN is not supplied and the namespace is empty. The namespace identifies which component owns the metric; without a URN, Beam relies on namespace+name to identify the metric, so an empty namespace is unusable. This is a fail-fast validation to prevent unidentifiable metrics.

Source

Thrown at sdks/python/apache_beam/metrics/metricbase.py:78

      namespace: Optional[str],
      name: Optional[str],
      urn: Optional[str] = None,
      labels: Optional[dict[str, str]] = None) -> None:
    """Initializes ``MetricName``.

    Note: namespace and name should be set for user metrics,
    urn and labels should be set for an arbitrary metric to package into a
    MonitoringInfo.

    Args:
      namespace: A string with the namespace of a metric.
      name: A string with the name of a metric.
      urn: URN to populate on a MonitoringInfo, when sending to RunnerHarness.
      labels: Labels to populate on a MonitoringInfo
    """
    if not urn:
      if not namespace:
        raise ValueError('Metric namespace must be non-empty')
      if not name:
        raise ValueError('Metric name must be non-empty')
    self.namespace = namespace
    self.name = name
    self.urn = urn
    self.labels = labels if labels else {}

  def __eq__(self, other):
    return (
        self.namespace == other.namespace and self.name == other.name and
        self.urn == other.urn and self.labels == other.labels)

  def __str__(self):
    if self.urn:
      return 'MetricName(namespace={}, name={}, urn={}, labels={})'.format(
          self.namespace, self.name, self.urn, self.labels)
    else:  # User counter case.
      return 'MetricName(namespace={}, name={})'.format(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass a non-empty namespace string, conventionally the class name or module that owns the metric, e.g. Metrics.counter(MyDoFn.__name__, 'elements_read').
  2. If you intentionally have no namespace, supply a urn instead — when urn is set, namespace/name validation is skipped.
  3. Guard dynamic namespace construction so empty results fall back to a default namespace string.

Example fix

// before
_ = Metrics.counter('', 'elements_read')
// after
_ = Metrics.counter('MyDoFn', 'elements_read')
Defensive patterns

Strategy: validation

Validate before calling

if not urn and not namespace:
    raise ValueError('namespace required when urn is not set')
metric = Metrics.counter(namespace, name)

Try / catch

try:
    metric = Metrics.counter(namespace, name)
except ValueError as e:
    metric = Metrics.counter('default-namespace', name)
    logger.warning('metric namespace rejected (%s), using default', e)

Prevention

When it happens

Trigger: Creating a Metric (or subclass such as Metrics.counter/deprecated Counter/Meter) with namespace='' or None while omitting the urn argument.

Common situations: Passing a variable that is an empty string as namespace; building metrics dynamically where the namespace is computed and comes back empty; calling Metric directly instead of via the Metrics facade and forgetting namespace.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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