XTLS/Xray-core · error
BrutalDown must be at least 65536 bytes per second
Error message
BrutalDown must be at least 65536 bytes per second
What it means
Same floor check as BrutalUp but for the downstream bandwidth: if brutalDown is set (> 0) and parses to less than 65536 bytes/second, config building fails. Unset (0) is allowed. The purpose is to prevent Brutal congestion control from being configured with an unusably small down rate.
Source
Thrown at infra/conf/transport_internet.go:242
}
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")
}
c.FinalMask.QuicParams.Congestion = strings.ToLower(c.FinalMask.QuicParams.Congestion)
switch c.FinalMask.QuicParams.Congestion {
case "", "brutal", "reno", "bbr":
case "force-brutal":
if up == 0 {
return nil, errors.New("force-brutal requires up")
}
default:
return nil, errors.New("unknown congestion control: ", c.FinalMask.QuicParams.Congestion, ", valid values: reno, bbr, brutal, force-brutal")
}
if (c.FinalMask.QuicParams.UdpHop.Interval.From != 0 && c.FinalMask.QuicParams.UdpHop.Interval.From < 5) || (c.FinalMask.QuicParams.UdpHop.Interval.To != 0 && c.FinalMask.QuicParams.UdpHop.Interval.To < 5) {
return nil, errors.New("Interval must be at least 5")
}
if c.FinalMask.QuicParams.InitStreamReceiveWindow > 0 && c.FinalMask.QuicParams.InitStreamReceiveWindow < 16384 {View on GitHub (pinned to 7d214f8b09)
Solutions
- Set brutalDown to at least 65536 bytes/second, e.g. "1 MBps".
- Or omit brutalDown if downstream rate should not be pinned.
- Remember the threshold is in bytes per second (65536 B/s = 524288 bps).
Example fix
// before
"quicParams": { "brutalDown": "64 kbps" }
// after
"quicParams": { "brutalDown": "1 MBps" } Defensive patterns
Strategy: validation
Validate before calling
func brutalDownOK(raw any) bool {
s, _ := raw.(string)
if s == "" { return true }
bps, err := parseBandwidthToBytesPerSec(s)
return err == nil && (bps == 0 || bps >= 65536)
} Prevention
- Use byte-based units ('512 kBps' minimum) for both brutal directions.
- Validate both directions together in one check before deploy.
- Do not reuse bitrate numbers from link specs without converting bits to bytes.
When it happens
Trigger: "quicParams": { "brutalDown": "64 kbps" } (64000 bits/s = 8000 B/s < 65536 B/s).
Common situations: Bits/bytes confusion; copying a down rate below 512 kBps; keeping a placeholder small value during testing.
Related errors
- BrutalUp must be at least 65536 bytes per second
- force-brutal requires up
- unknown bbr profile
- 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/4df4aacc6bc75fcb.
Report an issue: GitHub.