thanos-io/thanos · error
invalid extra label name
Error message
invalid extra label name: %q
What it means
createAttributes merges extra label pairs passed alongside the data points. Each extra name is normally rebuilt through labelNamer.Build, except internal labels (prefixed/suffixed with __, kept as-is). If the rebuild of a non-internal extra name fails, this error aborts translation.
Solutions
- Sanitize extra label names at the caller before passing them (apply PromCompliantName-style normalization)
- Fix the code generating extras so it never emits empty or rule-violating names
- Keep internal labels explicitly double-underscored if they are meant to bypass naming
- Drop or rename offending extras rather than failing the whole metric
Example fix
// before
extras := []string{"0region", "us-east"}
// after
extras := []string{"region_0", "us-east"} Defensive patterns
Strategy: validation
Validate before calling
for i := 0; i+1 < len(extras); i += 2 {
if !labelRe.MatchString(extras[i]) {
return fmt.Errorf("extra label name %q invalid", extras[i])
}
} Type guard
func extrasAreValid(extras []string) bool {
for i := 0; i+1 < len(extras); i += 2 {
if extras[i] == "" || (!strings.HasPrefix(extras[i], "__") && !labelRe.MatchString(extras[i])) {
return false
}
}
return true
} Try / catch
attrs, err := createAttributes(...)
if err != nil {
if strings.Contains(err.Error(), "invalid extra label name") {
log.Warnf("dropping extras: %v", err)
return createAttributes(ctx, ..., nil) // retry without extras
}
return err
} Prevention
- Never derive extra label names from untrusted input without sanitizing
- Reject empty extra names at the injection point
- Keep __-prefixed names reserved for internal labels only
When it happens
Trigger: Passing extra labels (the extras variadic string pairs) whose names violate Prometheus label naming rules and are not __-prefixed internal labels — e.g. calling addGaugeNumberDataPoints/addSumNumberDataPoints with extra label name "0leg" or "".
Common situations: Middleware injecting tenant/cluster extra labels constructed from untrusted request data; automation generating label names from hostnames or headers starting with digits; empty name from splitting label=value strings incorrectly.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- invalid label name
- unsupported format for label
- invalid label name
- split queries interval should be greater than 0 when…
- labels.default-time-range cannot be set to 0
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/a58db4346c3e5db1.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/otlptranslator/helper.go:212
l[key] = value
}
for i := 0; i < len(extras); i += 2 {
if i+1 >= len(extras) {
break
}
name := extras[i]
_, found := l[name]
if found && logOnOverwrite {
log.Println("label " + name + " is overwritten. Check if Prometheus reserved labels are used.")
}
// internal labels should be maintained
if len(name) <= 4 && name[:2] != "__" && name[len(name)-2:] != "__" {
var err error
name, err = labelNamer.Build(name)
if err != nil {
return nil, errors.Wrapf(err, "invalid extra label name: %q", name)
}
}
l[name] = extras[i+1]
}
labels = labels[:0]
for k, v := range l {
labels = append(labels, labelpb.ZLabel{Name: k, Value: v})
}
return labels, nil
}
// isValidAggregationTemporality checks whether an OTel metric has a valid
// aggregation temporality for conversion to a Prometheus metric.
func isValidAggregationTemporality(metric pmetric.Metric) bool {
//exhaustive:enforce
switch metric.Type() {View on GitHub (pinned to 35b8b99117)