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

  1. Use "tlshello" or "" for keyword behavior
  2. Use a single numeric range like "1-3" for packet-index-based fragmentation
  3. 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

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


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/c2d3f606241a4a8d. Report an issue: GitHub.