vitessio/vitess · error

unsupported balancer mode: %s (supported modes: %s)

Error message

unsupported balancer mode: %s (supported modes: %s)

What it means

NewTabletBalancer maps a balancer mode string to a balancer implementation; the default branch rejects unknown mode values listing the supported names. ModeCell is also explicitly rejected here because cell-aware routing is handled by the gateway itself, not the balancer factory.

Source

Thrown at go/vt/vtgate/balancer/balancer.go:167

//   - See the RFC here: https://github.com/vitessio/vitess/issues/12241
//   - "random": Random balancer that uniformly distributes load without cell affinity
//   - "session": Session balancer that pins a session to the same tablet for the duration of the session. If the tablet goes away, the session is automatically and transparently migrated to another tablet of the same type.
//
// Note: "cell" mode is handled by the gateway and does not create a balancer instance.
// operates as a round robin inside of the vtgate's cell
// Returns an error for unsupported modes.
func NewTabletBalancer(mode Mode, localCell string, vtGateCells []string) (TabletBalancer, error) {
	switch mode {
	case ModePreferCell:
		return newFlowBalancer(localCell, vtGateCells), nil
	case ModeRandom:
		return newRandomBalancer(localCell, vtGateCells), nil
	case ModeSession:
		return newSessionBalancer(localCell), nil
	case ModeCell:
		return nil, errors.New("cell mode should be handled by the gateway, not the balancer factory")
	default:
		return nil, fmt.Errorf("unsupported balancer mode: %s (supported modes: %s)", mode, strings.Join(GetAvailableModeNames(), ", "))
	}
}

func newFlowBalancer(localCell string, vtGateCells []string) TabletBalancer {
	return &flowBalancer{
		localCell:   localCell,
		vtGateCells: vtGateCells,
		allocations: map[discovery.KeyspaceShardTabletType]*targetAllocation{},
	}
}

type flowBalancer struct {
	//
	// Configuration
	//

	// The local cell for the vtgate
	localCell string

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Set the mode to one of the supported names listed in the error message (e.g. flow, random, session).
  2. Remove the 'cell' mode setting — cell-aware routing is default gateway behavior; use a supported mode or none.
  3. Check the config against the current version's mode list since names may have changed between releases.

Example fix

// before
balancerMode = "cel"
// after
balancerMode = "random" // or flow/session
Defensive patterns

Strategy: validation

Validate before calling

supported := balancer.GetAvailableModeNames()
if !slices.Contains(supported, cfg.TabletBalancerMode) {
    return fmt.Errorf("mode %q not supported; use one of %v", cfg.TabletBalancerMode, supported)
}

Try / catch

if _, err := balancer.NewTabletBalancer(mode, cell, cells); err != nil {
    if strings.Contains(err.Error(), "unsupported balancer mode") {
        log.Warn("falling back to default mode", "requested", mode)
    }
}

Prevention

When it happens

Trigger: Configuring vtgate with a --tablet-balancer-mode (or programmatic balancer mode) value that is not one of the defined modes, or explicitly choosing ModeCell which the factory refuses.

Common situations: Typo in the balancer mode config value (e.g. 'randomn'); copy of config from an older version using a removed mode name; setting 'cell' expecting the balancer to handle it when the gateway handles cell routing.

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/5dc1d58ce8c5dd56. Report an issue: GitHub.