{"record":{"id":"b44b18a2dd45640c","repo":"thanos-io/thanos","slug":"invalid-label-name-q-b44b18","errorCode":null,"errorMessage":"invalid label name: %q","messagePattern":"invalid label name: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/otlptranslator/helper.go","lineNumber":157,"sourceCode":"\t// XXX: Should we always drop service namespace/service name/service instance ID from the labels\n\t// (as they get mapped to other Prometheus labels)?\n\tattributes.Range(func(key string, value pcommon.Value) bool {\n\t\tif !slices.Contains(ignoreAttrs, key) {\n\t\t\tlabels = append(labels, labelpb.ZLabel{Name: key, Value: value.AsString()})\n\t\t}\n\t\treturn true\n\t})\n\tsort.Stable(ByLabelName(labels))\n\n\tlabelNamer := prometheustranslator.LabelNamer{\n\t\tUTF8Allowed: settings.AllowUTF8,\n\t}\n\t// map ensures no duplicate label names.\n\tl := make(map[string]string, maxLabelCount)\n\tfor _, label := range labels {\n\t\tfinalKey, err := labelNamer.Build(label.Name)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"invalid label name: %q\", label.Name)\n\t\t}\n\t\tif existingValue, alreadyExists := l[finalKey]; alreadyExists {\n\t\t\tl[finalKey] = existingValue + \";\" + label.Value\n\t\t} else {\n\t\t\tl[finalKey] = label.Value\n\t\t}\n\t}\n\n\tfor _, lbl := range promotedAttrs {\n\t\tnormalized, err := labelNamer.Build(lbl.Name)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"invalid promoted resource attribute name: %q\", lbl.Name)\n\t\t}\n\t\tif _, exists := l[normalized]; !exists {\n\t\t\tl[normalized] = lbl.Value\n\t\t}\n\t}\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/otlptranslator/helper.go#L139-L175","documentation":"createAttributes translates OTLP attribute keys into Prometheus label names via labelNamer.Build. When a metric attribute name cannot be converted to a valid Prometheus label name (after all normalization attempts fail), this error wraps the underlying naming failure and aborts translation of the whole metric.","triggerScenarios":"Sending OTLP metrics whose attribute key, even after sanitization by the namer, cannot become a valid label name — e.g. an attribute key starting with a digit after normalization, or an empty/entirely invalid key, in AddGauge/Sum/Histogram/Summary/ExponentialHistogram data point translation.","commonSituations":"Instrumented apps using numeric keys like {'2xx_requests': ...} or keys composed solely of special characters; proxies/SDKs forwarding raw telemetry with non-ASCII keys; tenant sending attributes violating Prometheus naming rules with TranslateOTLP without allow-utf8.","solutions":["Rename the OTLP attribute key in the emitting application to match Prometheus label name rules ([a-zA-Z_][a-zA-Z0-9_]*)","Sanitize keys at the collector/SDK side before export","Enable/verify the label-naming normalization settings (e.g. AllowUTF8 off means strict legacy names) and ensure keys pass it","Log and drop the offending attribute server-side instead of failing the metric"],"exampleFix":"// before: attribute with key \"2xx-total\"\nattrs.Add(\"2xx-total\", n)\n// after: valid label name\nattrs.Add(\"_2xx_total\", n)","handlingStrategy":"validation","validationCode":"// Go: validate attribute keys against label-name rules before export\nvar labelRe = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)\nfunc validLabelName(k string) bool { return labelRe.MatchString(k) }","typeGuard":"func isSafeLabelKey(k string) bool {\n    return k != \"\" && labelRe.MatchString(k)\n}","tryCatchPattern":"attrs, err := createAttributes(...)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid label name\") {\n        log.Warnf(\"dropping metric with bad attribute: %v\", err)\n        return nil // or sanitize and retry\n    }\n    return err\n}","preventionTips":["Enforce Prometheus label-name rules in your instrumentation helpers","Sanitize dynamic keys (tenant IDs, hostnames) before attaching as attributes","Test with worst-case keys: digits first, empty, non-ASCII"],"tags":["otlp","labels","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}