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

  1. Sanitize extra label names at the caller before passing them (apply PromCompliantName-style normalization)
  2. Fix the code generating extras so it never emits empty or rule-violating names
  3. Keep internal labels explicitly double-underscored if they are meant to bypass naming
  4. 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

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


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)