epi052/feroxbuster · error

Invalid request: Missing head/body separator

Error message

Invalid request: Missing head/body separator

What it means

parse_request_file locates the first header/body separator (`\r\n\r\n` or `\n\n`) in the raw request file. If neither separator is present, the file has no way to divide headers from the body, so the request is malformed and the function throws. A valid raw HTTP request always contains a blank line ending the header section.

Solutions

  1. Add a blank line after the headers to terminate the header section (`\r\n\r\n` or `\n\n`)
  2. Re-copy the raw request from the source (e.g. browser devtools 'copy as cURL' or HAR) including the separator
  3. Use CRLF line endings consistently when exporting the request file

Example fix

// before (request.txt)
GET / HTTP/1.1
Host: example.com
// after
GET / HTTP/1.1
Host: example.com

Defensive patterns

Strategy: validation

Validate before calling

let contents = std::fs::read(&path)?;
if !contents.windows(4).any(|w| w == b"\r\n\r\n") && !contents.windows(2).any(|w| w == b"\n\n") {
    return Err(anyhow!("request file has no head/body separator"));
}

Try / catch

match parse_request_file(&mut config) {
    Ok(()) => {},
    Err(e) => eprintln!("bad --request-file: {e}; ensure a blank line separates headers from body"),
}

Prevention

When it happens

Trigger: Providing a `--request-file` whose contents contain neither `\r\n\r\n` nor `\n\n` — e.g. just a request line with headers but no terminating blank line, or a plain URL/text pasted in.

Common situations: Copy-pasting requests from logs where the trailing blank line was dropped, using LF-only editors that strip the final empty line, or writing a body-less request without the closing CRLF CRLF.

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/f527af7a7447384d. Report an issue: GitHub.

Appendix: source

Thrown at src/config/utils.rs:457

    // find the first header/body separator
    // locate both \r\n\r\n and \n\n and pick whichever appears earliest,
    // so that a \r\n\r\n inside the body doesn't shadow a \n\n separator
    // that terminates the headers
    let crlf = contents.windows(4).position(|w| w == b"\r\n\r\n");
    let lf = contents.windows(2).position(|w| w == b"\n\n");

    let (sep_idx, sep_len) = match (crlf, lf) {
        (Some(c), Some(l)) => {
            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();

View on GitHub (pinned to 1f595dab5c)