{"record":{"id":"7bb52c643255c8f7","repo":"ducaale/xh","slug":"bad-content-range-header","errorCode":null,"errorMessage":"Bad Content-Range header","messagePattern":"Bad Content-Range header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/download.rs","lineNumber":212,"sourceCode":"        buffer = Box::new(open_opts.open(&dest_name)?);\n    } else if test_pretend_term() || io::stdout().is_terminal() {\n        let (new_name, handle) = open_new_file(get_file_name(&response, orig_url).into())?;\n        dest_name = new_name;\n        buffer = Box::new(handle);\n    } else {\n        dest_name = \"<stdout>\".into();\n        buffer = Box::new(io::stdout());\n    }\n\n    let starting_length: u64;\n    let total_length: Option<u64>;\n    if let Some(resume) = resume {\n        let header = response\n            .headers()\n            .get(CONTENT_RANGE)\n            .ok_or_else(|| anyhow!(\"Missing Content-Range header\"))?\n            .to_str()\n            .map_err(|_| anyhow!(\"Bad Content-Range header\"))?;\n        starting_length = resume;\n        total_length = Some(total_for_content_range(header, starting_length)?);\n    } else {\n        starting_length = 0;\n        total_length = get_content_length(response.headers());\n    }\n\n    let starting_time = Instant::now();\n\n    let pb = if quiet {\n        // Still counts the downloaded bytes, it just doesn't display anything.\n        ProgressBar::hidden()\n    } else if let Some(total_length) = total_length {\n        eprintln!(\n            \"Downloading {} to {:?}\",\n            HumanBytes(total_length - starting_length),\n            dest_name\n        );","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/ducaale/xh/blob/2404aceecc08b0b2d100fedc96f57745cd5904dc/src/download.rs#L194-L230","documentation":"The Content-Range header value retrieved during a resumed download is not valid UTF-8 (or otherwise not a valid header string), so it cannot be parsed. The client rejects it before attempting range parsing.","triggerScenarios":"download_file called with Some(resume) and response.headers().get(CONTENT_RANGE) returns a HeaderValue whose to_str() fails because the header bytes are not visible ASCII/UTF-8.","commonSituations":"Misbehaving or malicious server/proxy emitting non-ASCII bytes in headers; corrupted response through broken middleware; extremely unusual custom server implementations.","solutions":["Restart the download without resume (offset 0).","Inspect the raw response headers (curl -v) to identify the malformed value.","Update/bypass the proxy or middleware corrupting headers.","If the server is under your control, fix its Content-Range emission to valid ASCII per RFC 9110."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if let Some(v) = resp.headers().get(header::CONTENT_RANGE) {\n    if v.to_str().is_err() {\n        // treat as non-resumable, restart download\n    }\n}","typeGuard":"fn valid_content_range(resp: &Response) -> Option<&str> {\n    resp.headers().get(header::CONTENT_RANGE)?.to_str().ok()\n}","tryCatchPattern":"match download_file(url, Some(offset)) {\n    Err(e) if e.to_string().contains(\"Bad Content-Range\") => download_file(url, None),\n    other => other,\n}","preventionTips":["Treat any unparsable Content-Range as 'not resumable' and restart.","Inspect raw headers with curl -v when a server misbehaves.","Whitelist only trusted servers for resume operations.","Keep a retry counter to avoid resume loops against broken servers."],"tags":["download","http","resume","malformed-header"],"backgroundTag":"invalid-argument-format","analyzedSha":"2404aceecc08b0b2d100fedc96f57745cd5904dc","analyzedAt":"2026-09-13T19:13:33.814Z","contentChangedAt":"2026-09-13T19:13:33.814Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}