{"record":{"id":"7f8a4d30acd1b775","repo":"copy/v86","slug":"the-request-contains-an-invalid-header-s","errorCode":null,"errorMessage":"The request contains an invalid header: \"%s\"","messagePattern":"The request contains an invalid header: \"(.+?)\"","errorType":"console","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"src/browser/fetch_network.js","lineNumber":173,"sourceCode":"        target = new URL(first_line[1]);\n    }\n    else\n    {\n        target = new URL(\"http://host\" + first_line[1]);\n    }\n    if(typeof window !== \"undefined\" && target.protocol === \"http:\" && window.location.protocol === \"https:\")\n    {\n        // fix \"Mixed Content\" errors\n        target.protocol = \"https:\";\n    }\n\n    const req_headers = new Headers();\n    for(let i = 1; i < header_lines.length; ++i)\n    {\n        const header = this.net.parse_http_header(header_lines[i]);\n        if(!header)\n        {\n            console.warn('The request contains an invalid header: \"%s\"', header_lines[i]);\n            this.net.respond_text_and_close(this, 400, \"Bad Request\", `Invalid header in request: ${header_lines[i]}`);\n            return;\n        }\n        if(header.key.toLowerCase() === \"host\") target.host = header.value;\n        else req_headers.append(header.key, header.value);\n    }\n\n    if(!this.net.cors_proxy && /^\\d+\\.external$/.test(target.hostname))\n    {\n        dbg_log(\"Request to localhost: \" + target.href, LOG_FETCH);\n        const localport = parseInt(target.hostname.split(\".\")[0], 10);\n        if(!isNaN(localport) && localport > 0 && localport < 65536)\n        {\n            target.protocol = \"http:\";\n            target.hostname = \"localhost\";\n            target.port = localport.toString(10);\n        }\n        else","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/copy/v86/blob/180830d539dcc87db1a191febf6c914f516d102f/src/browser/fetch_network.js#L155-L191","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the client inside the VM to send well-formed HTTP/1.1 headers (each header must be 'Key: Value')","Check that the guest isn't sending HTTPS/TLS traffic to the plain-HTTP proxy port","Update the guest's HTTP client software / proxy configuration to standards-compliant output","If a specific header is intentionally nonstandard, extend parse_http_header handling or bypass the fetch backend for that traffic"],"exampleFix":"// before (guest request)\nfetch(\"http://host/\").setHeader(\"BadHeader NoColon\", \"\");\n// after\nfetch(\"http://host/\", { headers: { \"Accept\": \"*/*\" } }); // valid 'Key: Value' headers","handlingStrategy":"validation","validationCode":"function isWellFormedHeaderLine(line) {\n    const idx = line.indexOf(\":\");\n    return idx > 0 && /^[-!#$%&'*+.^_`|~0-9A-Za-z]+$/.test(line.slice(0, idx).trim()) &&\n    !/[\\r\\n]/.test(line);\n}\n// sanitize guest request headers before they reach the fake server\nif (!headers.every(isWellFormedHeaderLine)) fixOrRejectRequest();","typeGuard":"function isValidHttpHeader(line) {\n    const i = line.indexOf(\":\");\n    return i > 0 && line.slice(0, i).trim().length > 0 && !/[\\r\\n]/.test(line);\n}","tryCatchPattern":"// Not a thrown exception: intercept via the server's response handling\nif (response.status === 400 && /Invalid header in request:/.test(await response.text())) {\n    logMalformedGuestRequest();\n    retryWithSanitizedHeaders();\n}","preventionTips":["Ensure the guest's HTTP client emits standards-compliant 'Key: Value' headers","Never point plain-HTTP proxy settings at a TLS port (or vice versa)","Update old/buggy guest HTTP clients","Monitor console for this warning to spot misconfigured guest software early"],"tags":["http","fetch","bad-request","proxy"],"backgroundTag":"http-400-bad-request","analyzedSha":"180830d539dcc87db1a191febf6c914f516d102f","analyzedAt":"2026-08-31T22:39:37.599Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}