jaegertracing/jaeger · error
Field [%s]: Tag [%s] is not of the form key=value in 'tags'
Error message
Field [%s]: Tag [%s] is not of the form key=value in 'tags' string [%s]
What it means
metrics.Init() parses the `tags` struct tag as a comma-separated list of key=value pairs. If any pair in the tag string splits on '=' into something other than exactly two parts, Init returns this error naming the field, the offending pair, and the full tags string.
Source
Thrown at internal/metrics/metrics.go:61
histogramPtrType := reflect.TypeFor[Histogram]()
v := reflect.ValueOf(m).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
tags := make(map[string]string)
maps.Copy(tags, globalTags)
var histogramBuckets []float64
var timerBuckets []time.Duration
field := t.Field(i)
metric := field.Tag.Get("metric")
if metric == "" {
return fmt.Errorf("Field %s is missing a tag 'metric'", field.Name)
}
if tagString := field.Tag.Get("tags"); tagString != "" {
for tagPair := range strings.SplitSeq(tagString, ",") {
tag := strings.Split(tagPair, "=")
if len(tag) != 2 {
return fmt.Errorf(
"Field [%s]: Tag [%s] is not of the form key=value in 'tags' string [%s]",
field.Name, tagPair, tagString,
)
}
tags[tag[0]] = tag[1]
}
}
if bucketString := field.Tag.Get("buckets"); bucketString != "" {
switch {
case field.Type.AssignableTo(timerPtrType):
bucketValues := strings.Split(bucketString, ",")
for _, bucket := range bucketValues {
d, err := time.ParseDuration(bucket)
if err != nil {
return fmt.Errorf(
"Field [%s]: Bucket [%s] could not be parsed as duration in 'buckets' string [%s]",
field.Name, bucket, bucketString,
)View on GitHub (pinned to 806f444784)
Solutions
- Fix the named tag pair to be exactly key=value
- Remove empty/extra pairs from the tags string (no stray or trailing commas)
- Escape or avoid '=' inside tag values
- Verify every comma-separated segment has exactly one '='
Example fix
// before Requests *Counter `metric:"requests" tags:"service,"` // after Requests *Counter `metric:"requests" tags:"service=jaeger-query"`
Defensive patterns
Strategy: validation
Validate before calling
func checkTagsTag(s string) error {
for _, pair := range strings.Split(s, ",") {
if len(strings.Split(pair, "=")) != 2 {
return fmt.Errorf("bad tag pair %q in %q", pair, s)
}
}
return nil
} Try / catch
if err := metrics.Init(&m); err != nil {
if strings.Contains(err.Error(), "not of the form key=value") {
// correct the tags string reported in the error
}
return err
} Prevention
- Keep tag values free of '=' and ',' or restructure them
- Format tags strictly as key1=v1,key2=v2
- Lint struct tags with a tool (e.g. golangci-lint structcheck/tagliatelle)
- Count '=' per pair when hand-writing tags
When it happens
Trigger: A field's `tags:"..."` value containing a pair without '=' or with multiple '=' (e.g. `tags:"service,env=prod"` or `tags:"a=b=c"`) when Init/MustInit runs.
Common situations: Hand-writing tag lists and forgetting a '=value'; putting commas in a tag value without quoting/escaping; typos like `tags:"env prod"`.
Related errors
- Field %s is missing a tag 'metric'
- Field [%s]: Bucket [%s] could not be parsed as duration in '
- Field [%s]: Bucket [%s] could not be converted to float64 in
- Field [%s]: Buckets should only be defined for Timer and His
- Field %s is not a pointer to timer, gauge, or counter
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/7a8446d179509bf2.
Report an issue: GitHub.