vitessio/vitess · error

invalid metric name: %s

Error message

invalid metric name: %s

What it means

Each entry of req.AppCheckedMetrics must be a recognizable metric name (possibly a disaggregated per-item name like 'loadaverage.mysql'). base.DisaggregateMetricName parses the entry into its base metric; if parsing fails, the whole UpdateThrottlerConfig call is rejected.

Source

Thrown at go/vt/vtctl/grpcvtctldserver/server.go:2112

	span, ctx := trace.NewSpan(ctx, "VtctldServer.UpdateThrottlerConfig")
	defer span.Finish()

	defer panicHandler(&err)

	if req.Enable && req.Disable {
		return nil, errors.New("--enable and --disable are mutually exclusive")
	}

	if req.MetricName != "" && !base.KnownMetricNames.Contains(base.MetricName(req.MetricName)) {
		return nil, fmt.Errorf("unknown metric name: %s", req.MetricName)
	}

	if len(req.AppCheckedMetrics) > 0 {
		specifiedMetrics := map[base.MetricName]bool{}
		for _, metricName := range req.AppCheckedMetrics {
			_, knownMetric, err := base.DisaggregateMetricName(metricName)
			if err != nil {
				return nil, fmt.Errorf("invalid metric name: %s", metricName)
			}
			if _, ok := specifiedMetrics[knownMetric]; ok {
				return nil, fmt.Errorf("duplicate metric name: %s", knownMetric)
			}
			specifiedMetrics[knownMetric] = true
		}
	}

	update := func(throttlerConfig *topodatapb.ThrottlerConfig) *topodatapb.ThrottlerConfig {
		if throttlerConfig == nil {
			throttlerConfig = &topodatapb.ThrottlerConfig{}
		}
		if throttlerConfig.ThrottledApps == nil {
			throttlerConfig.ThrottledApps = make(map[string]*topodatapb.ThrottledAppRule)
		}
		if throttlerConfig.AppCheckedMetrics == nil {
			throttlerConfig.AppCheckedMetrics = make(map[string]*topodatapb.ThrottlerConfig_MetricNames)
		}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Validate each app-checked-metric entry against base.DisaggregateMetricName/known metric names and fix the offending entry.
  2. Ensure the per-item suffix syntax (e.g. '.mysql') is supported for the chosen metric.
  3. Remove the invalid entry from AppCheckedMetrics if it is not needed.

Example fix

// before
--app-checked-metrics "loadavg.mysql"
// after
--app-checked-metrics "loadaverage.mysql"
Defensive patterns

Strategy: validation

Validate before calling

for _, m := range req.AppCheckedMetrics {
    if _, _, err := base.DisaggregateMetricName(m); err != nil {
        return fmt.Errorf("bad app-checked-metric %q: %v", m, err)
    }
}

Prevention

When it happens

Trigger: Passing an entry in AppCheckedMetrics (e.g. --app-checked-metrics flag) that cannot be disaggregated into a known metric — malformed string, wrong separator, or unknown base metric name.

Common situations: Comma/space-separated list formatting mistakes on the CLI, entries like 'foo.bar' where 'foo' is not a known metric, or copy-pasted values from docs of a different Vitess version.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/91c1f4c8f2c514b5. Report an issue: GitHub.