thanos-io/thanos · error

invalid promoted resource attribute name

Error message

invalid promoted resource attribute name: %q

What it means

createAttributes also promotes configured resource attributes (promotedAttrs, e.g. job/instance mapped from OTLP resource) into labels. If a promoted resource attribute name fails labelNamer.Build, this error is returned, aborting metric translation.

Solutions

  1. Fix the promoted attribute name in your promotion config to a valid Prometheus label name
  2. Remove stale promotion entries for attributes no longer produced by the SDK
  3. Verify each configured key matches [a-zA-Z_][a-zA-Z0-9_]* (or is properly UTF-8 enabled and normalized)
  4. Test promotion config offline by running labelNamer.Build-equivalent sanitization on each entry

Example fix

# before (invalid promoted attr)
promotedAttrs: ["service.name", "k8s pod.name"]
# after
promotedAttrs: ["service_name", "k8s_pod_name"]
Defensive patterns

Strategy: validation

Validate before calling

for _, attr := range promotedAttrsConfig {
    if !labelRe.MatchString(attr) {
        return fmt.Errorf("promoted attribute %q is not a valid label name", attr)
    }
}

Type guard

func validPromotedAttrs(attrs []string) bool {
    for _, a := range attrs { if !labelRe.MatchString(a) { return false } }
    return true
}

Try / catch

attrs, err := createAttributes(...)
if err != nil {
    if strings.Contains(err.Error(), "promoted resource attribute") {
        log.Errorf("bad promotion config: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Configured resource-to-label promotion attributes whose names fail label normalization — e.g. a custom promotion mapping containing a key that cannot become a valid Prometheus label name, triggered from any add*DataPoints path.

Common situations: Operators adding custom resource attribute promotions (via --receive.otel-promoted-attrs / collector config) with malformed key names; upstream rename of resource attributes leaving stale promotion entries.

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/ef070ccd334b7ccf. Report an issue: GitHub.

Appendix: source

Thrown at pkg/receive/otlptranslator/helper.go:169

	}
	// map ensures no duplicate label names.
	l := make(map[string]string, maxLabelCount)
	for _, label := range labels {
		finalKey, err := labelNamer.Build(label.Name)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid label name: %q", label.Name)
		}
		if existingValue, alreadyExists := l[finalKey]; alreadyExists {
			l[finalKey] = existingValue + ";" + label.Value
		} else {
			l[finalKey] = label.Value
		}
	}

	for _, lbl := range promotedAttrs {
		normalized, err := labelNamer.Build(lbl.Name)
		if err != nil {
			return nil, errors.Wrapf(err, "invalid promoted resource attribute name: %q", lbl.Name)
		}
		if _, exists := l[normalized]; !exists {
			l[normalized] = lbl.Value
		}
	}

	// Map service.name + service.namespace to job
	if haveServiceName {
		val := serviceName.AsString()
		if serviceNamespace, ok := resourceAttrs.Get(conventions.AttributeServiceNamespace); ok {
			val = fmt.Sprintf("%s/%s", serviceNamespace.AsString(), val)
		}
		l[model.JobLabel] = val
	}
	// Map service.instance.id to instance
	if haveInstanceID {
		l[model.InstanceLabel] = instance.AsString()
	}

View on GitHub (pinned to 35b8b99117)