jaegertracing/jaeger · error

Field %s is not a pointer to timer, gauge, or counter

Error message

Field %s is not a pointer to timer, gauge, or counter

What it means

metrics.Init() reflects over struct fields and only knows how to instantiate *Timer, *Gauge, and *Counter fields. A field with any other type (or a non-pointer metric type) falls into the default case and returns this error naming the field, because the library cannot allocate a metric object for it.

Source

Thrown at internal/metrics/metrics.go:132

				Tags: tags,
				Help: help,
			})
		case field.Type.AssignableTo(timerPtrType):
			obj = factory.Timer(TimerOptions{
				Name:    metric,
				Tags:    tags,
				Help:    help,
				Buckets: timerBuckets,
			})
		case field.Type.AssignableTo(histogramPtrType):
			obj = factory.Histogram(HistogramOptions{
				Name:    metric,
				Tags:    tags,
				Help:    help,
				Buckets: histogramBuckets,
			})
		default:
			return fmt.Errorf(
				"Field %s is not a pointer to timer, gauge, or counter",
				field.Name,
			)
		}
		v.Field(i).Set(reflect.ValueOf(obj))
	}
	return nil
}

View on GitHub (pinned to 806f444784)

Solutions

  1. Change the field to a *Timer, *Gauge, or *Counter pointer
  2. Add the missing '*' to make the field a pointer
  3. Move non-metric fields out of the metrics struct
  4. Check the import: use the timer/gauge/counter types this package expects

Example fix

// before
Latency timer.Timer `metric:"latency"`
// after
Latency *timer.Timer `metric:"latency"`
Defensive patterns

Strategy: type-guard

Validate before calling

func checkMetricFieldTypes(s any) error {
    t := reflect.TypeOf(s)
    for i := 0; i < t.NumField(); i++ {
        ft := t.Field(i).Type
        if ft.Kind() != reflect.Pointer {
            return fmt.Errorf("field %s must be a pointer metric", t.Field(i).Name)
        }
    }
    return nil
}

Type guard

func isSupportedMetricField(t reflect.StructField) bool {
    return t.Type.AssignableTo(timerPtrType) ||
        t.Type.AssignableTo(gaugePtrType) ||
        t.Type.AssignableTo(counterPtrType)
}

Prevention

When it happens

Trigger: A metrics struct containing a field of a type other than *timer.Timer, *gauge.Gauge, or *counter.Counter (e.g. a plain Timer value without pointer, a string/int helper field, or a custom metric type) when Init runs.

Common situations: Adding metadata or non-metric fields to the metrics struct; forgetting the '*' so the field is a value instead of a pointer; using a metric type from another package the Init switch does not recognize.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/d4ef9a29833c68da. Report an issue: GitHub.