vitessio/vitess · error
Invalid CandidatePromotionRule: %v
Error message
Invalid CandidatePromotionRule: %v
What it means
promotionrule.Parse rejects any rule name outside the known set (prefer, neutral, prefer_not, must_not) with 'Invalid CandidatePromotionRule'. This guards candidate selection during reparents from mislabeled tablets.
Source
Thrown at go/vt/vtctl/reparentutil/promotionrule/promotion_rule.go:65
func (r *CandidatePromotionRule) BetterThan(other CandidatePromotionRule) bool {
otherOrder, ok := promotionRuleOrderMap[other]
if !ok {
return false
}
return promotionRuleOrderMap[*r] < otherOrder
}
// Parse returns a CandidatePromotionRule by name.
// It returns an error if there is no known rule by the given name.
func Parse(ruleName string) (CandidatePromotionRule, error) {
switch ruleName {
case "prefer", "neutral", "prefer_not", "must_not":
return CandidatePromotionRule(ruleName), nil
case "must":
return CandidatePromotionRule(""), fmt.Errorf("CandidatePromotionRule: %v not supported yet", ruleName)
default:
return CandidatePromotionRule(""), fmt.Errorf("Invalid CandidatePromotionRule: %v", ruleName)
}
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Find the tablet with the bad label (vtctldclient GetTablets) and correct its promotion_rule to one of: prefer, neutral, prefer_not, must_not (all lowercase)
- Re-run the reparent after fixing the label
- If set by automation, fix the automation's allowed-values list and add lowercase normalization
Example fix
// before promotion_rule=Prefer_Not // after promotion_rule=prefer_not
Defensive patterns
Strategy: validation
Validate before calling
// Normalize and validate before applying tablet labels
rule = strings.ToLower(strings.TrimSpace(rule))
if !slices.Contains([]string{"prefer", "neutral", "prefer_not", "must_not"}, rule) {
return fmt.Errorf("invalid CandidatePromotionRule %q", rule)
} Type guard
func isValidCandidatePromotionRule(s string) bool {
switch promotionrule.CandidatePromotionRule(s) {
case promotionrule.Prefer, promotionrule.Neutral, promotionrule.PreferNot, promotionrule.MustNot:
return true
}
return false
} Try / catch
if _, err := promotionrule.Parse(rule); err != nil {
if strings.Contains(err.Error(), "Invalid CandidatePromotionRule") {
// fix the tablet label to one of prefer/neutral/prefer_not/must_not
}
} Prevention
- Keep rule names lowercase everywhere
- Whitelist values in any UI/automation that writes tablet labels
- Audit tablet labels for typos before PRS/ERS
When it happens
Trigger: During PRS/ERS, a tablet record's candidate promotion rule string is anything unrecognized (typo like 'prefered', 'MUST_NOT', empty convention mismatch) and gets passed to promotionrule.Parse.
Common situations: Case-sensitivity mistakes ('Prefer'); typos in tablet labels/tags set via vtctldclient; older tooling writing deprecated rule names; hand-edited tablet labels.
Related errors
- CandidatePromotionRule: %v not supported yet
- durability policy %v not found
- cell mode should be handled by the gateway, not the balancer
- package %s is not under %s
- unknown handling name %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b5ed895ab334ade8.
Report an issue: GitHub.