{"record":{"id":"fc59e2320b36b308","repo":"XTLS/Xray-core","slug":"lengthmin-can-t-be-0","errorCode":null,"errorMessage":"LengthMin can't be 0","messagePattern":"LengthMin can't be 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/freedom.go","lineNumber":125,"sourceCode":"\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}\n\t\t\tconfig.Fragment.IntervalMin = uint64(c.Fragment.Interval.From)\n\t\t\tconfig.Fragment.IntervalMax = uint64(c.Fragment.Interval.To)\n\t\t}\n\n\t\t{\n\t\t\tif c.Fragment.MaxSplit != nil {\n\t\t\t\tconfig.Fragment.MaxSplitMin = uint64(c.Fragment.MaxSplit.From)\n\t\t\t\tconfig.Fragment.MaxSplitMax = uint64(c.Fragment.MaxSplit.To)\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/freedom.go#L107-L143","documentation":"Thrown when the freedom fragment 'length' range has a lower bound of 0. After converting Length.From to LengthMin, Build() rejects zero-length segments because splitting TCP data into zero-byte pieces is invalid. Distinct from the missing-length error: here the range exists but starts at 0.","triggerScenarios":"\"fragment\": {\"length\": \"0-200\", ...} — ParseRangeString succeeds, LengthMin becomes 0, and the explicit check fires.","commonSituations":"Using \"0-N\" as a shorthand for 'any length'; generator defaults starting ranges at 0.","solutions":["Set the length lower bound to at least 1, e.g. \"100-200\".","Pick realistic MTU-sized ranges (e.g. \"100-200\" bytes) rather than 0-based ones.","Validate fragment ranges in your config generator."],"exampleFix":"// before\n\"length\": \"0-200\"\n\n// after\n\"length\": \"100-200\"","handlingStrategy":"validation","validationCode":"if fragment.Length != nil && fragment.Length.From < 1 {\n    return errors.New(\"fragment length range must start at >= 1 byte\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never use 0 as the lower bound of fragment length.","Prefer realistic byte ranges (e.g. 100-200)."],"tags":["go","xray","freedom","fragment","config","numeric-range"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}