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
- Validate each app-checked-metric entry against base.DisaggregateMetricName/known metric names and fix the offending entry.
- Ensure the per-item suffix syntax (e.g. '.mysql') is supported for the chosen metric.
- 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
- Parse metric entries with base.DisaggregateMetricName in the CLI wrapper before sending the RPC
- Generate AppCheckedMetrics from config rather than free-form strings
- Test metric list parsing in CI
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
- unknown metric name: %s
- duplicate metric name: %s
- no app indicated
- throttler not open
- failed to update throttler: %v err: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/91c1f4c8f2c514b5.
Report an issue: GitHub.