{"record":{"id":"0138af7b5b258870","repo":"valyala/fasthttp","slug":"missing-byte-range-in-q","errorCode":null,"errorMessage":"missing byte range in %q","messagePattern":"missing byte range in %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"fs.go","lineNumber":1489,"sourceCode":"\tctx.SetStatusCode(statusCode)\n}\n\ntype byteRangeUpdater interface {\n\tUpdateByteRange(startPos, endPos int) error\n}\n\n// ParseByteRange parses 'Range: bytes=...' header value.\n//\n// It follows https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 .\nfunc ParseByteRange(byteRange []byte, contentLength int) (startPos, endPos int, err error) {\n\tb := byteRange\n\tif !bytes.HasPrefix(b, strBytes) {\n\t\treturn 0, 0, fmt.Errorf(\"unsupported range units: %q: expecting %q\", byteRange, strBytes)\n\t}\n\n\tb = b[len(strBytes):]\n\tif len(b) == 0 || b[0] != '=' {\n\t\treturn 0, 0, fmt.Errorf(\"missing byte range in %q\", byteRange)\n\t}\n\tb = b[1:]\n\n\tn := bytes.IndexByte(b, '-')\n\tif n < 0 {\n\t\treturn 0, 0, fmt.Errorf(\"missing the end position of byte range in %q\", byteRange)\n\t}\n\n\tif n == 0 {\n\t\tv, err := ParseUint(b[n+1:])\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tif contentLength <= 0 {\n\t\t\treturn 0, 0, fmt.Errorf(\"byte range %q is invalid for empty content\", byteRange)\n\t\t}\n\t\tstartPos := max(contentLength-v, 0)\n\t\treturn startPos, contentLength - 1, nil","sourceCodeStart":1471,"sourceCodeEnd":1507,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1471-L1507","documentation":"After confirming the 'bytes' unit, ParseByteRange requires the next character to be '=' introducing the byte-range-set (e.g. bytes=0-499). If the header ends right after the unit or lacks '=', it reports the full header value as malformed.","triggerScenarios":"A client sends Range: bytes (no '='), Range: bytes:0-9 (wrong separator), or an empty range set like 'bytes=' with nothing after; any direct ParseByteRange call with such a value.","commonSituations":"Hand-crafted or buggy custom HTTP clients; fuzzed/malicious requests probing the server; template-generated headers with a missing '='.","solutions":["Correct the client to send Range: bytes=<start>-<end>","Add middleware that drops or 400s malformed Range headers before file serving","Sanitize log input since the raw value is echoed with %q","For direct ParseByteRange use, pre-validate with a regexp like ^bytes=\\d*-\\d*(,\\d*-\\d*)*$"],"exampleFix":"// before\nRange: bytes 0-99\n// after\nRange: bytes=0-99","handlingStrategy":"validation","validationCode":"if !regexp.MustCompile(`^bytes=`).Match(hdr) {\n    return errors.New(\"range must start with 'bytes='\")\n}","typeGuard":"func wellFormedRange(r []byte) bool {\n    return bytes.HasPrefix(r, []byte(\"bytes\")) && len(r) > len(\"bytes\") && r[len(\"bytes\")] == '='\n}","tryCatchPattern":"start, end, err := fs.ParseByteRange(hdr, cl)\nif err != nil && strings.Contains(err.Error(), \"missing byte range\") {\n    http.StatusRequestedRangeNotSatisfiable // or serve full body\n}","preventionTips":["Always include '=' after the unit when constructing Range headers","Fuzz-test your public endpoints with malformed Range headers","Strip malformed ranges at the load-balancer/proxy layer","Use high-level client helpers (SetByteRange) instead of hand-building headers"],"tags":["http","range-header","validation","fasthttp"],"backgroundTag":"missing-byte-range","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}