XTLS/Xray-core · error
unknown bbr profile
Error message
unknown bbr profile
What it means
Thrown when streamSettings.finalMask.quicParams.bbrProfile (after lowercasing) is not one of '', 'conservative', 'standard', or 'aggressive' (the bbr.Profile values). Empty is allowed and normalized to 'standard'. Any other string is rejected before the QuicParams block is built.
Source
Thrown at infra/conf/transport_internet.go:226
}
config.Tcpmasks = append(config.Tcpmasks, serial.ToTypedMessage(u))
}
for _, mask := range c.FinalMask.Udp {
u, err := mask.Build(false)
if err != nil {
return nil, errors.New("failed to build mask with type ", mask.Type).Base(err)
}
config.Udpmasks = append(config.Udpmasks, serial.ToTypedMessage(u))
}
if c.FinalMask.QuicParams != nil {
profile := strings.ToLower(c.FinalMask.QuicParams.BbrProfile)
switch profile {
case "", string(bbr.ProfileConservative), string(bbr.ProfileStandard), string(bbr.ProfileAggressive):
if profile == "" {
profile = string(bbr.ProfileStandard)
}
default:
return nil, errors.New("unknown bbr profile")
}
up, err := c.FinalMask.QuicParams.BrutalUp.Bps()
if err != nil {
return nil, err
}
down, err := c.FinalMask.QuicParams.BrutalDown.Bps()
if err != nil {
return nil, err
}
if up > 0 && up < 65536 {
return nil, errors.New("BrutalUp must be at least 65536 bytes per second")
}
if down > 0 && down < 65536 {
return nil, errors.New("BrutalDown must be at least 65536 bytes per second")
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Set bbrProfile to one of: "conservative", "standard", "aggressive".
- Or remove the field entirely to get the default 'standard' profile.
Example fix
// before
"quicParams": { "bbrProfile": "fast" }
// after
"quicParams": { "bbrProfile": "aggressive" } Defensive patterns
Strategy: validation
Validate before calling
var validBbrProfiles = map[string]bool{"": true, "conservative": true, "standard": true, "aggressive": true}
func bbrProfileOK(qp map[string]any) bool {
p, _ := qp["bbrProfile"].(string)
return validBbrProfiles[strings.ToLower(p)]
} Type guard
func hasBbrProfile(qp map[string]any) bool {
_, ok := qp["bbrProfile"]
return ok
} Prevention
- Expose bbrProfile as an enum in your config generator (not free text).
- Treat the profile list (conservative/standard/aggressive) as versioned API; re-check on upgrade.
- Omit the field when the default standard profile is acceptable.
When it happens
Trigger: Setting "quicParams": { "bbrProfile": "fast" } (or any string besides conservative/standard/aggressive) under finalMask.
Common situations: Guessing profile names ('high', 'max', 'balanced') instead of the three defined bbr profiles; capitalization is fine (case-insensitive) but the word itself must match.
Related errors
- BrutalUp must be at least 65536 bytes per second
- BrutalDown must be at least 65536 bytes per second
- force-brutal requires up
- unknown congestion control: + c.FinalMask.QuicParams.Conges
- Interval must be at least 5
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/35b8dade63203a80.
Report an issue: GitHub.