{"record":{"id":"8a6087c5f620abc0","repo":"valyala/fasthttp","slug":"unsupported-range-units-q-expecting-q","errorCode":null,"errorMessage":"unsupported range units: %q: expecting %q","messagePattern":"unsupported range units: %q: expecting %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"fs.go","lineNumber":1484,"sourceCode":"\t}\n\thdr.noDefaultContentType = true\n\tif len(hdr.ContentType()) == 0 {\n\t\tctx.SetContentType(ff.contentType)\n\t}\n\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}","sourceCodeStart":1466,"sourceCodeEnd":1502,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/fs.go#L1466-L1502","documentation":"ParseByteRange parses the HTTP 'Range' request header and only supports the 'bytes' unit per RFC 2616 section 14.35. If the header does not start with 'bytes', it returns this error naming the received value and the expected unit.","triggerScenarios":"A client sends Range: items=0-9, Range: foobar=..., or a localized/odd unit string to a fasthttp FileServer / ServeFile / FS handler that processes range requests; any caller of fs.ParseByteRange passing a value whose unit is not exactly 'bytes'.","commonSituations":"Custom HTTP clients generating non-standard range units (e.g. 'items=' from some RSS/JSON clients); hand-written Range headers in tests or scripts; reverse-proxy clients translating ranges into other units.","solutions":["Fix the client to send standard syntax: Range: bytes=start-end","Validate/rewrite the Range header in middleware before it reaches fasthttp, or strip unsupported Range headers so the server responds 200 with full body","If you only need 'accepting any range', ignore the header instead of forwarding invalid units","In your own code calling ParseByteRange, bytes.HasPrefix(value, []byte(\"bytes\")) first"],"exampleFix":"// before (client)\nreq.SetByteRange(\"items=0-99\")\n// after\nreq.SetByteRangeBytes(0, 99) // sends Range: bytes=0-99","handlingStrategy":"validation","validationCode":"re := regexp.MustCompile(`^bytes=\\d*-\\d*(,\\d*-\\d*)*$`)\nif rangeHdr := req.Header.Peek(\"Range\"); len(rangeHdr) > 0 && !re.Match(rangeHdr) {\n    req.Header.Del(\"Range\") // let server respond 200 with full body\n}","typeGuard":"func hasBytesUnit(r []byte) bool {\n    return bytes.HasPrefix(r, []byte(\"bytes\"))\n}","tryCatchPattern":"start, end, err := fs.ParseByteRange(hdr, cl)\nif err != nil {\n    // unsupported unit: serve full content instead of failing\n    start, end = 0, int(cl)-1\n}","preventionTips":["Only ever emit 'bytes=' units in custom HTTP clients","Normalize incoming Range headers in middleware before they reach handlers","Drop (don't forward) Range headers you cannot parse","Test with curl -H 'Range: bytes=0-99' to verify server behavior"],"tags":["http","range-header","validation","fasthttp"],"backgroundTag":"unsupported-range-units","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}