valyala/fasthttp · warning
missing byte range in %q
Error message
missing byte range in %q
What it means
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.
Source
Thrown at fs.go:1489
ctx.SetStatusCode(statusCode)
}
type byteRangeUpdater interface {
UpdateByteRange(startPos, endPos int) error
}
// ParseByteRange parses 'Range: bytes=...' header value.
//
// It follows https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 .
func ParseByteRange(byteRange []byte, contentLength int) (startPos, endPos int, err error) {
b := byteRange
if !bytes.HasPrefix(b, strBytes) {
return 0, 0, fmt.Errorf("unsupported range units: %q: expecting %q", byteRange, strBytes)
}
b = b[len(strBytes):]
if len(b) == 0 || b[0] != '=' {
return 0, 0, fmt.Errorf("missing byte range in %q", byteRange)
}
b = b[1:]
n := bytes.IndexByte(b, '-')
if n < 0 {
return 0, 0, fmt.Errorf("missing the end position of byte range in %q", byteRange)
}
if n == 0 {
v, err := ParseUint(b[n+1:])
if err != nil {
return 0, 0, err
}
if contentLength <= 0 {
return 0, 0, fmt.Errorf("byte range %q is invalid for empty content", byteRange)
}
startPos := max(contentLength-v, 0)
return startPos, contentLength - 1, nilView on GitHub (pinned to c96f600972)
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*)*$
Example fix
// before Range: bytes 0-99 // after Range: bytes=0-99
Defensive patterns
Strategy: validation
Validate before calling
if !regexp.MustCompile(`^bytes=`).Match(hdr) {
return errors.New("range must start with 'bytes='")
} Type guard
func wellFormedRange(r []byte) bool {
return bytes.HasPrefix(r, []byte("bytes")) && len(r) > len("bytes") && r[len("bytes")] == '='
} Try / catch
start, end, err := fs.ParseByteRange(hdr, cl)
if err != nil && strings.Contains(err.Error(), "missing byte range") {
http.StatusRequestedRangeNotSatisfiable // or serve full body
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Hand-crafted or buggy custom HTTP clients; fuzzed/malicious requests probing the server; template-generated headers with a missing '='.
Related errors
- unsupported range units: %q: expecting %q
- missing the end position of byte range in %q
- the start position of byte range cannot exceed the end posit
- fasthttp: non-numeric chars found
- byte range %q is invalid for empty content
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/0138af7b5b258870.
Report an issue: GitHub.