{"record":{"id":"bb2e49ebaa9097f5","repo":"apache/pulsar","slug":"label-name-s-is-invalid-must-match-the-regex","errorCode":null,"errorMessage":"Label name '%s' is invalid: must match the regex [a-zA-Z_][a-zA-Z0-9_]*","messagePattern":"Label name '(.+?)' is invalid: must match the regex \\[a-zA-Z_\\]\\[a-zA-Z0-9_\\]\\*","errorType":"http","errorClass":"org.apache.pulsar.broker.admin.RestException","httpStatus":400,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java","lineNumber":2578,"sourceCode":"        }\n\n        // Pulsar reserves all labels starting with \"pulsar_\" or \"pulsar.\" for internal use.\n        if (labelName.endsWith(\"pulsar.\") || labelName.endsWith(\"pulsar_\")) {\n            throw new RestException(Response.Status.BAD_REQUEST,\n                    String.format(\"Label name '%s' is invalid: Pulsar reserves all labels starting with 'pulsar_' \"\n                            + \"or 'pulsar.' for internal use\", labelName));\n        }\n\n        // OpenTelemetry reserves all labels starting with \"otel_\" or \"otel.\" for internal use.\n        if (labelName.startsWith(\"otel.\") || labelName.startsWith(\"otel_\")) {\n            throw new RestException(Response.Status.BAD_REQUEST,\n                    String.format(\"Label name '%s' is invalid: OpenTelemetry reserves all labels starting with \"\n                            + \"'otel_' or 'otel.' for internal use\", labelName));\n        }\n\n        boolean matches = METRICS_LABEL_NAME_PATTERN.matcher(labelName).matches();\n        if (!matches) {\n            throw new RestException(Response.Status.BAD_REQUEST,\n                String.format(\"Label name '%s' is invalid: must match the regex [a-zA-Z_][a-zA-Z0-9_]*\", labelName));\n        }\n\n    }\n}\n","sourceCodeStart":2560,"sourceCodeEnd":2584,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java#L2560-L2584","documentation":"Prometheus label names must match the pattern [a-zA-Z_][a-zA-Z0-9_]* — start with a letter or underscore and contain only letters, digits, and underscores. Pulsar enforces this via METRICS_LABEL_NAME_PATTERN in isValidMetricsName and rejects non-conforming names with HTTP 400.","triggerScenarios":"Registering a metrics label containing invalid characters such as hyphens, dots, spaces, or starting with a digit (e.g. \"my-label\", \"my.label\", \"1label\") via the broker metrics API.","commonSituations":"Using metric/label names copied from systems allowing dots or dashes (e.g. JMX or StatsD names); programmatically generating labels from hostnames or topic names containing dots and slashes; config files with human-readable label names.","solutions":["Sanitize the label name to match [a-zA-Z_][a-zA-Z0-9_]*: replace invalid characters with underscores and ensure it starts with a letter or underscore.","Move problematic characters (dots, slashes) into the label VALUE instead of the name.","Add a client-side regex check before calling the broker to fail fast with a clearer message."],"exampleFix":"// before\nmetrics.registerLabel(\"my-label.name\");\n\n// after\nString safe = label.replaceAll(\"[^a-zA-Z0-9_]\", \"_\");\nif (!safe.matches(\"[a-zA-Z_][a-zA-Z0-9_]*\")) {\n    safe = \"_\" + safe;\n}\nmetrics.registerLabel(safe);","handlingStrategy":"validation","validationCode":"boolean isValidPrometheusName(String s) {\n    return s != null && s.matches(\"[a-zA-Z_][a-zA-Z0-9_]*\");\n}","typeGuard":"String toSafeLabelName(String raw) {\n    if (raw == null) return null;\n    String s = raw.replaceAll(\"[^a-zA-Z0-9_]\", \"_\");\n    return s.isEmpty() || Character.isDigit(s.charAt(0)) ? \"_\" + s : s;\n}","tryCatchPattern":"try {\n    metricsApi.registerLabel(labelName);\n} catch (RestException e) {\n    if (e.getResponse().getStatus() == 400) {\n        metricsApi.registerLabel(toSafeLabelName(labelName));\n    }\n}","preventionTips":["Run every label name through the [a-zA-Z_][a-zA-Z0-9_]* regex before sending","Convert dots/hyphens in source names (JMX, hostnames) to underscores","Put high-cardinality detail in label values, not names"],"tags":["metrics","prometheus","validation","regex"],"backgroundTag":"metrics-label-name-invalid","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}