epi052/feroxbuster · error · anyhow::Error

Request headers contain invalid UTF-8

Error message

Request headers contain invalid UTF-8

What it means

parse_request_file reads a raw HTTP request file and splits head from body. Only the head section is decoded as UTF-8 because HTTP framing is expected to be ascii/UTF-8 compatible; if the header bytes fail std::str::from_utf8, the function bails with this error.

Solutions

  1. Re-save the request file as UTF-8 (or plain ASCII) without BOM or binary content in the header section
  2. Ensure headers and body are separated by a proper blank line (\r\n\r\n) so binary body bytes are not treated as headers
  3. Remove any binary/compressed body from the file and supply the body via the CLI instead

Example fix

// before
"POST / HTTP/1.1\r\nHost: x\r\n\xff\xfe" // invalid bytes in head
// after
"POST / HTTP/1.1\r\nHost: x\r\n\r\n" // clean head; body via --data
Defensive patterns

Strategy: validation

Validate before calling

let bytes = std::fs::read(path)?;
let head_end = find_separator(&bytes); // locate \r\n\r\n
std::str::from_utf8(&bytes[..head_end]).map_err(|_| anyhow!("headers are not UTF-8"))?;

Type guard

fn is_utf8_head(bytes: &[u8], sep_idx: usize) -> bool { std::str::from_utf8(&bytes[..sep_idx]).is_ok() }

Try / catch

match parse_request_file(path) { Err(e) if e.to_string().contains("invalid UTF-8") => eprintln!("re-save request file as UTF-8"), Err(e) => return Err(e), Ok(cfg) => use(cfg) }

Prevention

When it happens

Trigger: Providing a raw request file whose header section (everything before the head/body separator) contains bytes that are not valid UTF-8 — e.g. Latin-1 encoded headers, binary data, or a separator misdetection that pulls binary body bytes into the head.

Common situations: Exporting a request from a proxy in raw binary form, copying a request with non-UTF-8 encodings, or saving a request with a compressed/binary body and no proper blank-line separator so the split index lands inside binary data.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of epi052/feroxbuster@1f595dab5c (2026-09-13). Data as JSON: /api/errors/b6a34c371b49f1ff. Report an issue: GitHub.

Appendix: source

Thrown at src/config/utils.rs:467

            if c <= l {
                (c, 4)
            } else {
                (l, 2)
            }
        }
        (Some(c), None) => (c, 4),
        (None, Some(l)) => (l, 2),
        (None, None) => bail!("Invalid request: Missing head/body separator"),
    };

    // split the request head and body
    let head_bytes = &contents[..sep_idx];
    let body_bytes = &contents[sep_idx + sep_len..];

    // decode only the head; HTTP framing is generally ascii/utf-8
    // compatible
    let head = std::str::from_utf8(head_bytes)
        .map_err(|_| anyhow::anyhow!("Request headers contain invalid UTF-8"))?;

    // normalize line endings in the decoded head
    let normalized = head.replace("\r\n", "\n");

    // we only want to use the request's body bytes if the user hasn't
    // overridden it on the cli
    if config.data.is_empty() {
        config.data = body_bytes.to_vec();
    }

    // begin parsing the request line and normalized headers
    let mut head_parts = normalized.split("\n");

    let Some(request_line) = head_parts.next() else {
        bail!("Invalid request: Missing request line");
    };

    if request_line.is_empty() {

View on GitHub (pinned to 1f595dab5c)