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
- Supply a non-empty label name that matches [a-zA-Z_][a-zA-Z0-9_]*.
- Check the metrics/label configuration source (broker.conf, YAML, JSON) for missing or blank name fields.
- 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
- Validate label names with the Prometheus regex before any metrics registration
- Never derive label names from unparsed config keys that may be missing or blank
- Keep a shared constant/util for label-name validation across your metrics tooling
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
- Label name '%s' is invalid: Prometheus reserves all labels s
- Label name '%s' is invalid: Pulsar reserves all labels start
- Label name '%s' is invalid: must match the regex [a-zA-Z_][a
- Label name '%s' is invalid: OpenTelemetry reserves all label
- numInitialSegments must be >= 1
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/ad932e6e81b083ce.
Report an issue: GitHub.