{"record":{"id":"c2d3f606241a4a8d","repo":"XTLS/Xray-core","slug":"invalid-packetsfrom-c2d3f6","errorCode":null,"errorMessage":"Invalid PacketsFrom","messagePattern":"Invalid PacketsFrom","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/transport_finalmask.go","lineNumber":256,"sourceCode":"\tLengths  []Int32Range `json:\"lengths\"`\n\tDelays   []Int32Range `json:\"delays\"`\n\tMaxSplit Int32Range   `json:\"maxSplit\"`\n}\n\nfunc (c *FragmentMask) Build() (proto.Message, error) {\n\tconfig := &fragment.Config{}\n\n\tswitch strings.ToLower(c.Packets) {\n\tcase \"tlshello\":\n\t\tconfig.PacketsFrom = 0\n\t\tconfig.PacketsTo = 1\n\tcase \"\":\n\t\tconfig.PacketsFrom = 0\n\t\tconfig.PacketsTo = 0\n\tdefault:\n\t\tfrom, to, err := ParseRangeString(c.Packets)\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"Invalid PacketsFrom\").Base(err)\n\t\t}\n\t\tconfig.PacketsFrom = int64(from)\n\t\tconfig.PacketsTo = int64(to)\n\t\tif config.PacketsFrom == 0 {\n\t\t\treturn nil, errors.New(\"PacketsFrom can't be 0\")\n\t\t}\n\t}\n\n\tif len(c.Lengths) > 0 {\n\t\tfor _, r := range c.Lengths {\n\t\t\tconfig.LengthsMin = append(config.LengthsMin, int64(r.From))\n\t\t\tconfig.LengthsMax = append(config.LengthsMax, int64(r.To))\n\t\t}\n\t} else {\n\t\tconfig.LengthsMin = append(config.LengthsMin, int64(c.Length.From))\n\t\tconfig.LengthsMax = append(config.LengthsMax, int64(c.Length.To))\n\t}\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/transport_finalmask.go#L238-L274","documentation":"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.","triggerScenarios":"\"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).","commonSituations":"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.","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"],"exampleFix":"// before\n\"packets\": \"1,3\"\n// after\n\"packets\": \"1-3\"","handlingStrategy":"validation","validationCode":"const p = cfg.packets ?? '';\nconst rangeOk = /^(\\d+)(-(\\d+))?$/.test(p);\nif (p !== '' && p !== 'tlshello' && !rangeOk) throw new Error(`invalid packets value: ${p}`);\nif (rangeOk && parseInt(p) === 0) throw new Error('packets range cannot start at 0');","typeGuard":"const isPacketsSpec = (v: string) => v === '' || v === 'tlshello' || /^\\d+(-\\d+)?$/.test(v);","tryCatchPattern":null,"preventionTips":["Use only tlshello, empty, or N-M numeric ranges","Never use comma lists in packets"],"tags":["xray","go","transport","fragment","validation"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}