fatedier/frp · error
unrecognized feature gate: %s
Error message
unrecognized feature gate: %s
What it means
featureGate.SetValues (via Set) was given a feature name that was never registered with Add. The gate keeps a known-features map; setting any key outside it fails atomically before state is persisted. This mirrors Kubernetes feature-gate semantics and protects against silently ignoring typos.
Source
Thrown at pkg/policy/featuregate/feature_gate.go:118
f.enabled.Store(map[Feature]bool{})
return f
}
// SetFromMap sets feature gate values from a map[string]bool
func (f *featureGate) SetFromMap(m map[string]bool) error {
f.lock.Lock()
defer f.lock.Unlock()
// Copy existing state
known := maps.Clone(f.known.Load().(map[Feature]FeatureSpec))
enabled := maps.Clone(f.enabled.Load().(map[Feature]bool))
// Apply the new settings
for k, v := range m {
k := Feature(k)
featureSpec, ok := known[k]
if !ok {
return fmt.Errorf("unrecognized feature gate: %s", k)
}
if featureSpec.LockToDefault && featureSpec.Default != v {
return fmt.Errorf("cannot set feature gate %v to %v, feature is locked to %v", k, v, featureSpec.Default)
}
enabled[k] = v
}
// Persist the changes
f.known.Store(known)
f.enabled.Store(enabled)
return nil
}
// Add adds features to the feature gate
func (f *featureGate) Add(features map[Feature]FeatureSpec) error {
f.lock.Lock()
defer f.lock.Unlock()
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- List valid gates via the gate's String()/known map to find the exact accepted names
- Correct the typo or drop the removed gate from your configuration
- If the gate should exist, ensure Add() ran before SetValues (initialization order)
Example fix
// before
fg.Set(map[string]bool{
"SupportXTCPCQuic": true, // never registered
})
// after (use a gate actually registered by Add)
fg.Set(map[string]bool{
"SomeRegisteredGate": true,
}) Defensive patterns
Strategy: validation
Validate before calling
// Check gate existence before setting
all, _ := fg.KnownFeatures() // or export the known map
for k := range requested {
if _, ok := all[k]; !ok {
return fmt.Errorf("unknown feature gate %q; available: %v", k, all)
}
}
return fg.Set(requested) Try / catch
if err := fg.Set(requested); err != nil && strings.Contains(err.Error(), "unrecognized feature gate") {
// fail fast on typos; do not silently ignore
return err
} Prevention
- Fail startup on unrecognized gates rather than skipping them — they are almost always typos
- Keep feature-gate config in version control and review it on every frp upgrade
When it happens
Trigger: Calling Set(map[string]bool{"SomeFeature": true}) where "SomeFeature" is not in f.known — typo, feature removed in this version, or gate not yet populated via Add.
Common situations: Carrying old feature-flag config into a frp version that renamed/removed a gate; typo in the featureGates config string; setting a gate before the owning package registered it.
Related errors
- cannot set feature gate %v to %v, feature is locked to %v
- feature gate %q with different spec already exists: %v
- ErrHealthCheckType
- unit not support
- type is required
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/5b75aebcc5f21f0f.
Report an issue: GitHub.