XTLS/Xray-core · error
Invalid PacketsFrom
Error message
Invalid PacketsFrom
What it means
FragmentMask.Build (infra/conf/transport_finalmask.go:256) parses the fragment setting's "packets" field. Only "tlshello" (fragment only the TLS ClientHello) and "" (fragment everything) are literal keywords; anything else must parse as a numeric range via ParseRangeString (e.g. "1-3", "2"). If that range parse fails, "Invalid PacketsFrom" wraps the range-parser error.
Source
Thrown at infra/conf/transport_finalmask.go:256
Lengths []Int32Range `json:"lengths"`
Delays []Int32Range `json:"delays"`
MaxSplit Int32Range `json:"maxSplit"`
}
func (c *FragmentMask) Build() (proto.Message, error) {
config := &fragment.Config{}
switch strings.ToLower(c.Packets) {
case "tlshello":
config.PacketsFrom = 0
config.PacketsTo = 1
case "":
config.PacketsFrom = 0
config.PacketsTo = 0
default:
from, to, err := ParseRangeString(c.Packets)
if err != nil {
return nil, errors.New("Invalid PacketsFrom").Base(err)
}
config.PacketsFrom = int64(from)
config.PacketsTo = int64(to)
if config.PacketsFrom == 0 {
return nil, errors.New("PacketsFrom can't be 0")
}
}
if len(c.Lengths) > 0 {
for _, r := range c.Lengths {
config.LengthsMin = append(config.LengthsMin, int64(r.From))
config.LengthsMax = append(config.LengthsMax, int64(r.To))
}
} else {
config.LengthsMin = append(config.LengthsMin, int64(c.Length.From))
config.LengthsMax = append(config.LengthsMax, int64(c.Length.To))
}
View on GitHub (pinned to 7d214f8b09)
Solutions
- Use "tlshello" or "" for keyword behavior
- Use a single numeric range like "1-3" for packet-index-based fragmentation
- Verify the string only contains digits, an optional dash, and nothing else
Example fix
// before "packets": "1,3" // after "packets": "1-3"
Defensive patterns
Strategy: validation
Validate before calling
const p = cfg.packets ?? '';
const rangeOk = /^(\d+)(-(\d+))?$/.test(p);
if (p !== '' && p !== 'tlshello' && !rangeOk) throw new Error(`invalid packets value: ${p}`);
if (rangeOk && parseInt(p) === 0) throw new Error('packets range cannot start at 0'); Type guard
const isPacketsSpec = (v: string) => v === '' || v === 'tlshello' || /^\d+(-\d+)?$/.test(v);
Prevention
- Use only tlshello, empty, or N-M numeric ranges
- Never use comma lists in packets
When it happens
Trigger: "packets":"1tlshello", "packets":"1,2" (comma lists unsupported), "packets":"1..3" (double dot), or "packets":"all". Valid forms: "tlshello", "", "1", "1-3", "3-1" depending on parser tolerance (single range only).
Common situations: Porting fragment configs from other tools that accept comma-separated packet indices; using "0-1" intending 'first packet' — note 0 triggers the separate PacketsFrom!=0 check; missing quotes turning the value into invalid JSON earlier.
Related errors
- PacketsFrom can't be 0
- last lengths entry min can't be 0
- Invalid PacketsFrom
- invalid randRange
- len(item.Packet) > 0 && item.Rand.To > 0
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/c2d3f606241a4a8d.
Report an issue: GitHub.