{"record":{"id":"144bea39e7f1a767","repo":"XTLS/Xray-core","slug":"packetsfrom-can-t-be-0","errorCode":null,"errorMessage":"PacketsFrom can't be 0","messagePattern":"PacketsFrom can't be 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/freedom.go","lineNumber":114,"sourceCode":"\t\tswitch strings.ToLower(c.Fragment.Packets) {\n\t\tcase \"tlshello\":\n\t\t\t// TLS Hello Fragmentation (into multiple handshake messages)\n\t\t\tconfig.Fragment.PacketsFrom = 0\n\t\t\tconfig.Fragment.PacketsTo = 1\n\t\tcase \"\":\n\t\t\t// TCP Segmentation (all packets)\n\t\t\tconfig.Fragment.PacketsFrom = 0\n\t\t\tconfig.Fragment.PacketsTo = 0\n\t\tdefault:\n\t\t\t// TCP Segmentation (range)\n\t\t\tfrom, to, err := ParseRangeString(c.Fragment.Packets)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.New(\"Invalid PacketsFrom\").Base(err)\n\t\t\t}\n\t\t\tconfig.Fragment.PacketsFrom = uint64(from)\n\t\t\tconfig.Fragment.PacketsTo = uint64(to)\n\t\t\tif config.Fragment.PacketsFrom == 0 {\n\t\t\t\treturn nil, errors.New(\"PacketsFrom can't be 0\")\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tif c.Fragment.Length == nil {\n\t\t\t\treturn nil, errors.New(\"Length can't be empty\")\n\t\t\t}\n\t\t\tconfig.Fragment.LengthMin = uint64(c.Fragment.Length.From)\n\t\t\tconfig.Fragment.LengthMax = uint64(c.Fragment.Length.To)\n\t\t\tif config.Fragment.LengthMin == 0 {\n\t\t\t\treturn nil, errors.New(\"LengthMin can't be 0\")\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tif c.Fragment.Interval == nil {\n\t\t\t\treturn nil, errors.New(\"Interval can't be empty\")\n\t\t\t}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/freedom.go#L96-L132","documentation":"Thrown when the freedom outbound's fragment packets range parses successfully but its lower bound is 0. A zero starting packet is meaningless for TCP segmentation (packet numbering starts at 1), so Build() rejects PacketsFrom == 0 after converting the parsed range. Only reachable on the numeric-range branch, not for \"tlshello\" or \"\".","triggerScenarios":"\"fragment\": {\"packets\": \"0-5\"} or \"0-0\" — any range whose from value is 0. ParseRangeString succeeds, then the explicit zero check fires.","commonSituations":"Assuming packet indices are zero-based; auto-generated ranges starting at 0.","solutions":["Start the range at 1: use \"1-5\" instead of \"0-5\".","To fragment all packets, omit \"packets\" or set it to \"\" rather than \"0-0\".","For TLS ClientHello splitting use \"tlshello\"."],"exampleFix":"// before\n\"packets\": \"0-3\"\n\n// after\n\"packets\": \"1-3\"","handlingStrategy":"validation","validationCode":"if from, _, err := ParseRangeString(fragment.Packets); err == nil && from < 1 {\n    return errors.New(\"fragment.packets range must start at 1\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat packet numbering as 1-based.","Use \"\" (all packets) instead of \"0-0\"."],"tags":["go","xray","freedom","fragment","config","numeric-range"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}