{"id":"b9b9afedb9e1a46e","repo":"actix/actix-web","slug":"invalid-range-header-range-starts-after-end-of-co","errorCode":null,"errorMessage":"invalid Range header: range starts after end of content","messagePattern":"invalid Range header: range starts after end of content","errorType":"exception","errorClass":"ParseRangeErr","httpStatus":416,"severity":"warning","filePath":"actix-files/src/range.rs","lineNumber":30,"sourceCode":"impl From<http_range::HttpRangeParseError> for HttpRangeParseError {\n    fn from(err: http_range::HttpRangeParseError) -> Self {\n        match err {\n            http_range::HttpRangeParseError::InvalidRange => Self::InvalidRange,\n            http_range::HttpRangeParseError::NoOverlap => Self::NoOverlap,\n        }\n    }\n}\n\n#[derive(Debug, Clone, Error)]\n#[non_exhaustive]\npub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);\n\nimpl fmt::Display for ParseRangeErr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\"invalid Range header: \")?;\n        f.write_str(match self.0 {\n            HttpRangeParseError::InvalidRange => \"invalid syntax\",\n            HttpRangeParseError::NoOverlap => \"range starts after end of content\",\n        })\n    }\n}\n\n/// HTTP Range header representation.\n#[derive(Debug, Clone, Copy)]\npub struct HttpRange {\n    /// Start of range.\n    pub start: u64,\n\n    /// Length of range.\n    pub length: u64,\n}\n\nimpl HttpRange {\n    /// Parses Range HTTP header string as per RFC 2616.\n    ///\n    /// `header` is HTTP Range header (e.g. `bytes=0-9`).","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/actix/actix-web/blob/937960ca67f20e14ffe2a075bf6d4593502be12c/actix-files/src/range.rs#L12-L48","documentation":"Raised by HttpRange::parse (range.rs:50) when the http_range crate returns HttpRangeParseError::NoOverlap: the header parsed successfully but every requested start offset lies beyond the file size. actix-files maps this in NamedFile::into_response (named.rs:609-624) to a 416 Range Not Satisfiable response with 'Content-Range: bytes */<size>'. Syntactically valid, semantically unsatisfiable.","triggerScenarios":"The resource is small but the client asks for a far-later offset, e.g. file is 1000 bytes and the request is 'Range: bytes=5000-' or 'Range: bytes=1500-2000'. Also occurs when a file was truncated/rotated between the client receiving its size and issuing the range request.","commonSituations":"Resuming a download after the server file was replaced with a shorter one, requesting a byte range computed from a stale Content-Length, or video players seeking past the end of a media file.","solutions":["Have the client re-fetch Content-Length and restart the range request within bounds.","On the server, ensure the 416 response includes 'Content-Range: bytes */<size>' (actix-files does this automatically) so clients can self-correct.","For dynamic endpoints, validate the requested range against the actual payload length before responding.","Check that the file was not truncated or replaced between HEAD and GET."],"exampleFix":"// before: client uses stale size\nRange: bytes=5000-5999   (file is only 1000 bytes)\n\n// after: client clamps to real size or restarts\nRange: bytes=0-999","handlingStrategy":"validation","validationCode":"// Clamp requested ranges to the known content size before issuing the request.\nfn clamp_range(start: u64, end: Option<u64>, size: u64) -> Option<(u64, u64)> {\n    if start >= size { return None } // would trigger NoOverlap\n    let end = end.map(|e| e.min(size - 1)).unwrap_or(size - 1);\n    if start > end { return None }\n    Some((start, end))\n}","typeGuard":null,"tryCatchPattern":"// Same 416 path as syntax errors; actix-files handles it.\nmatch HttpRange::parse(range_header, file_size) {\n    Ok(ranges) if !ranges.is_empty() => serve(ranges[0]),\n    _ => respond_416(file_size),\n}","preventionTips":["Re-fetch Content-Length before resuming a range download.","Detect file replacement (ETag / Last-Modified mismatch) and restart from byte 0.","Handle 416 in the client by restarting the full download."],"tags":["http","range-header","actix-files","client-error"],"analyzedSha":"937960ca67f20e14ffe2a075bf6d4593502be12c","analyzedAt":"2026-08-06T01:15:46.978Z","schemaVersion":2}