copy/v86 · warning

The request contains an invalid header: "%s"

Error message

The request contains an invalid header: "%s"

What it means

The fake HTTP server (fetch_network) parses each request header line with net.parse_http_header; a line that doesn't split into a valid key/value pair logs a console warning and the server responds with 400 Bad Request, closing the connection. This is a server-side response behavior, not an exception — the message is the warning text, where %s is the offending raw header line.

Source

Thrown at src/browser/fetch_network.js:173

        target = new URL(first_line[1]);
    }
    else
    {
        target = new URL("http://host" + first_line[1]);
    }
    if(typeof window !== "undefined" && target.protocol === "http:" && window.location.protocol === "https:")
    {
        // fix "Mixed Content" errors
        target.protocol = "https:";
    }

    const req_headers = new Headers();
    for(let i = 1; i < header_lines.length; ++i)
    {
        const header = this.net.parse_http_header(header_lines[i]);
        if(!header)
        {
            console.warn('The request contains an invalid header: "%s"', header_lines[i]);
            this.net.respond_text_and_close(this, 400, "Bad Request", `Invalid header in request: ${header_lines[i]}`);
            return;
        }
        if(header.key.toLowerCase() === "host") target.host = header.value;
        else req_headers.append(header.key, header.value);
    }

    if(!this.net.cors_proxy && /^\d+\.external$/.test(target.hostname))
    {
        dbg_log("Request to localhost: " + target.href, LOG_FETCH);
        const localport = parseInt(target.hostname.split(".")[0], 10);
        if(!isNaN(localport) && localport > 0 && localport < 65536)
        {
            target.protocol = "http:";
            target.hostname = "localhost";
            target.port = localport.toString(10);
        }
        else

View on GitHub (pinned to 180830d539)

Solutions

  1. Fix the client inside the VM to send well-formed HTTP/1.1 headers (each header must be 'Key: Value')
  2. Check that the guest isn't sending HTTPS/TLS traffic to the plain-HTTP proxy port
  3. Update the guest's HTTP client software / proxy configuration to standards-compliant output
  4. If a specific header is intentionally nonstandard, extend parse_http_header handling or bypass the fetch backend for that traffic

Example fix

// before (guest request)
fetch("http://host/").setHeader("BadHeader NoColon", "");
// after
fetch("http://host/", { headers: { "Accept": "*/*" } }); // valid 'Key: Value' headers
Defensive patterns

Strategy: validation

Validate before calling

function isWellFormedHeaderLine(line) {
    const idx = line.indexOf(":");
    return idx > 0 && /^[-!#$%&'*+.^_`|~0-9A-Za-z]+$/.test(line.slice(0, idx).trim()) &&
    !/[\r\n]/.test(line);
}
// sanitize guest request headers before they reach the fake server
if (!headers.every(isWellFormedHeaderLine)) fixOrRejectRequest();

Type guard

function isValidHttpHeader(line) {
    const i = line.indexOf(":");
    return i > 0 && line.slice(0, i).trim().length > 0 && !/[\r\n]/.test(line);
}

Try / catch

// Not a thrown exception: intercept via the server's response handling
if (response.status === 400 && /Invalid header in request:/.test(await response.text())) {
    logMalformedGuestRequest();
    retryWithSanitizedHeaders();
}

Prevention

When it happens

Trigger: The guest OS sends an HTTP request containing a malformed header line (no colon, invalid characters, or a badly formed continuation) to a fetch-based network-backed server; on_data_http iterates header_lines[i] for i>=1 and any parse failure triggers the 400 path.

Common situations: Guest software producing non-conformant HTTP (custom tools, old clients, binary junk sent to port 80); a URL fetcher inside the VM hitting the proxy with garbage (e.g. plain TLS bytes sent to an HTTP port); misconfigured guest proxy settings pointing at the wrong port.

Related errors


AI-assisted analysis of copy/v86@180830d539 (2026-08-31). Data as JSON: /api/errors/7f8a4d30acd1b775. Report an issue: GitHub.