aio-libs/aiohttp · warning · ValueError
range not in acceptable format
Error message
range not in acceptable format
What it means
Raised as ValueError by BaseRequest.http_range (aiohttp/web_request.py:613) when the Range header is present but does not match the regex '^bytes=(\d*)-(\d*)$'. aiohttp only supports the RFC 7233 'bytes=' range unit; any other unit (e.g. 'items='), missing '=' , extra whitespace, or malformed syntax causes re.findall to return no groups and IndexError is caught and re-raised as this ValueError.
Source
Thrown at aiohttp/web_request.py:613
parsed = parse_cookie_header(self.headers.get(hdrs.COOKIE, ""))
# Extract values from Morsel objects
return MappingProxyType({name: morsel.value for name, morsel in parsed})
@reify
def http_range(self) -> "slice[int, int, int]":
"""The content of Range HTTP header.
Return a slice instance.
"""
rng = self._headers.get(hdrs.RANGE)
start, end = None, None
if rng is not None:
try:
pattern = r"^bytes=(\d*)-(\d*)$"
start, end = re.findall(pattern, rng, re.ASCII)[0]
except IndexError: # pattern was not found in header
raise ValueError("range not in acceptable format")
end = int(end) if end else None
start = int(start) if start else None
if start is None and end is not None:
# end with no start is to return tail of content
start = -end
end = None
if start is not None and end is not None:
# end is inclusive in range header, exclusive for slice
end += 1
if start >= end:
raise ValueError("start cannot be after end")
if start is end is None: # No valid range supplied
raise ValueError("No start or end of range specified")View on GitHub (pinned to c0ef574e29)
Solutions
- Validate the Range header format before relying on request.http_range, returning HTTPRequestedRangeNotSatisfiable or HTTPBadRequest on parse failure.
- Wrap request.http_range access in try/except ValueError and treat it as 'no range requested'.
- Make sure clients send 'Range: bytes=start-end' exactly (lowercase 'bytes=' allowed, but the unit must be bytes).
Example fix
// before
rng = request.http_range # ValueError on bad header
# after
try:
rng = request.http_range
except ValueError:
raise web.HTTPBadRequest(text="Invalid Range header") Defensive patterns
Strategy: try-catch
Validate before calling
import re
rng = request.headers.get("Range", "")
if rng and not re.match(r"^bytes=\d*-\d*$", rng):
raise web.HTTPBadRequest(text="Invalid Range header") Type guard
def is_valid_range_header(value: str) -> bool:
import re
return bool(re.match(r"^bytes=\d*-\d*$", value)) Try / catch
try:
rng = request.http_range
except ValueError:
raise web.HTTPBadRequest(text="Invalid Range header") Prevention
- Validate Range header syntax before relying on request.http_range.
- Let FileResponse handle Range natively if you only need partial-file serving.
- Audit non-standard clients sending 'items=' or other range units.
When it happens
Trigger: Accessing request.http_range (directly or via FileResponse, which reads it implicitly) on a request whose Range header looks like 'items=0-10', 'bytes 0-10' (space instead of =), 'bytes=-', or '0-10' (missing 'bytes=' prefix).
Common situations: Custom clients sending non-standard range units; copy-pasted Range header from a different protocol (WebDAV, S3 partial-object); proxies that rewrite or corrupt Range; tests with manually crafted headers.
Related errors
- No start or end of range specified
- start cannot be after end
- Method cannot contain non-token characters {method!r} (found
- Invalid Content-Length header: {content_length_hdr!r}
- compress must be one of True, False, 'deflate', or 'gzip'
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/e7f97e93bd3ac5a4.json.
Report an issue: GitHub.