apache/pulsar · error · org.apache.pulsar.broker.admin.RestException

Label name cannot be null or empty

Error message

Label name cannot be null or empty

What it means

isValidMetricsName validates a user-supplied Prometheus metrics label name before it is registered. A null or empty label name cannot form a valid label, so the broker rejects the request with HTTP 400. This guard exists because Prometheus label names must be non-empty and must not collide with reserved prefixes.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java:2552

        return healthChecker;
    }

    // https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
    public void validateCustomMetricLabelKeys(Set<String> allowedCustomMetricLabelKeys) {
        if (allowedCustomMetricLabelKeys == null) {
            return;
        }
        boolean exposeCustomTopicMetricLabelsEnabled = config.isExposeCustomTopicMetricLabelsEnabled();
        if (exposeCustomTopicMetricLabelsEnabled) {
            for (String labelKey : allowedCustomMetricLabelKeys) {
                isValidMetricsName(labelKey);
            }
        }
    }

    private static void isValidMetricsName(String labelName) {
        if (labelName == null || labelName.isEmpty()) {
            throw new RestException(Response.Status.BAD_REQUEST, "Label name cannot be null or empty");
        }

        // Prometheus reserves all labels starting with "__" for internal use.
        if (labelName.startsWith("__")) {
            throw new RestException(Response.Status.BAD_REQUEST,
                    String.format("Label name '%s' is invalid: Prometheus reserves all labels starting with '__' "
                            + "for internal use", labelName));
        }

        // Pulsar reserves all labels starting with "pulsar_" or "pulsar." for internal use.
        if (labelName.endsWith("pulsar.") || labelName.endsWith("pulsar_")) {
            throw new RestException(Response.Status.BAD_REQUEST,
                    String.format("Label name '%s' is invalid: Pulsar reserves all labels starting with 'pulsar_' "
                            + "or 'pulsar.' for internal use", labelName));
        }

        // OpenTelemetry reserves all labels starting with "otel_" or "otel." for internal use.
        if (labelName.startsWith("otel.") || labelName.startsWith("otel_")) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Supply a non-empty label name that matches [a-zA-Z_][a-zA-Z0-9_]*.
  2. Check the metrics/label configuration source (broker.conf, YAML, JSON) for missing or blank name fields.
  3. Add caller-side validation to reject null/blank label names before sending them to the broker.

Example fix

// before
String labelName = config.get("label"); // may be null
broker.metricsRegister("my_metric", labelName, value);

// after
String labelName = config.get("label");
if (labelName == null || labelName.isEmpty()) {
    throw new IllegalArgumentException("metrics label name is required");
}
broker.metricsRegister("my_metric", labelName, value);
Defensive patterns

Strategy: validation

Validate before calling

void requireValidLabelName(String name) {
    if (name == null || name.isEmpty()) throw new IllegalArgumentException("label name required");
    if (!name.matches("[a-zA-Z_][a-zA-Z0-9_]*")) throw new IllegalArgumentException("invalid label name: " + name);
}

Type guard

boolean isValidLabelName(String name) {
    return name != null && name.matches("[a-zA-Z_][a-zA-Z0-9_]*");
}

Try / catch

try {
    metricsApi.registerLabel(labelName);
} catch (RestException e) {
    if (e.getResponse().getStatus() == 400) {
        log.error("Rejected label name '{}': fix and resubmit", labelName);
    }
}

Prevention

When it happens

Trigger: Registering or updating broker metrics with an additional label whose name is null or an empty string, e.g. via the metrics admin endpoint or code that passes an unset label name into PulsarService.isValidMetricsName.

Common situations: A metrics configuration entry with a missing name key; programmatic metric registration where the label name variable is uninitialized; YAML/JSON config where the label name field was omitted.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/ad932e6e81b083ce. Report an issue: GitHub.