vitessio/vitess · error

failed to update throttler

Error message

failed to update throttler: %v err: %v

What it means

UpdateConfiguration wraps any error returned by the individual throttler's own UpdateConfiguration and re-raises it with the throttler name for context. The throttler rejected the supplied configuration.

Solutions

  1. Read the wrapped err text to see the throttler's validation failure
  2. Correct the Configuration values (valid MaxRate >= 0, valid names) and retry
  3. If resetting, use ResetConfiguration instead of partial invalid updates
  4. Check protobuf field types when constructing throttlerdatapb.Configuration

Example fix

// before
cfg.MaxRate = -5 // invalid
mgr.UpdateConfiguration(ctx, name, cfg, copyZeroValues)
// after
cfg.MaxRate = 0 // 0 means disabled
mgr.UpdateConfiguration(ctx, name, cfg, copyZeroValues)
Defensive patterns

Strategy: validation

Validate before calling

if cfg.MaxRate < 0 { return errors.New("MaxRate must be >= 0") }
if cfg.Threshold < 0 { return errors.New("Threshold must be >= 0") }
for _, a := range cfg.IgnoreAppNames { if a == "" { return errors.New("empty app name") } }

Try / catch

if _, err := manager.UpdateConfiguration(ctx, name, cfg, copyZeroValues); err != nil {
    if strings.Contains(err.Error(), "failed to update throttler") {
        return fmt.Errorf("invalid throttler config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Manager.UpdateConfiguration where t.UpdateConfiguration (the per-throttler implementation, e.g. in throttler.go) fails — typically because the Configuration proto contains invalid values (e.g. MaxRate, MaxReplicationLag, IgnoreAppNames constraints) that the throttler validates.

Common situations: Sending a ThrottlerUpdateConfiguration RPC with an out-of-range max rate or malformed app-name list; the underlying throttler rejects it and the manager wraps the cause.

Related errors


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

Appendix: source

Thrown at go/vt/throttler/manager.go:158

	return configurations, nil
}

// UpdateConfiguration implements the "Manager" interface.
func (m *managerImpl) UpdateConfiguration(throttlerName string, configuration *throttlerdatapb.Configuration, copyZeroValues bool) ([]string, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	// Note: The calls to t.UpdateConfiguration() below return no error but the
	// called protobuf library functions may panic. This is fine because the
	// throttler RPC service has a panic handler which will catch this.

	if throttlerName != "" {
		t, ok := m.throttlers[throttlerName]
		if !ok {
			return nil, fmt.Errorf("throttler: %v does not exist", throttlerName)
		}
		if err := t.UpdateConfiguration(configuration, copyZeroValues); err != nil {
			return nil, fmt.Errorf("failed to update throttler: %v err: %v", throttlerName, err)
		}
		return []string{throttlerName}, nil
	}

	for name, t := range m.throttlers {
		if err := t.UpdateConfiguration(configuration, copyZeroValues); err != nil {
			return nil, fmt.Errorf("failed to update throttler: %v err: %v", name, err)
		}
	}
	return m.throttlerNamesLocked(), nil
}

// ResetConfiguration implements the "Manager" interface.
func (m *managerImpl) ResetConfiguration(throttlerName string) ([]string, error) {
	m.mu.Lock()
	defer m.mu.Unlock()

	if throttlerName != "" {

View on GitHub (pinned to 01a25a7d17)