{"record":{"id":"79369f45b4af5be6","repo":"sveltejs/kit","slug":"the-protocol-header-header-specified-protocol","errorCode":null,"errorMessage":"The ${protocol_header} header specified ${protocol} which is an invalid protocol scheme. It should only contain the protocol scheme (e.g. `https`)","messagePattern":"The (.+?) header specified (.+?) which is an invalid protocol scheme\\. It should only contain the protocol scheme \\(e\\.g\\. `https`\\)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-bun/src/handler.js","lineNumber":73,"sourceCode":"\t\tconsole.error(\n\t\t\t`Could not determine request origin: ${error instanceof Error ? error.message : String(error)}`\n\t\t);\n\t\treturn new Response('Bad Request', { status: 400 });\n\t}\n}\n\n/**\n * @param {Request} request\n * @param {URL} url\n * @returns {string}\n */\nfunction get_origin(request, url) {\n\t// assume TLS terminates upstream, like adapter-node; an http origin would fail CSRF checks\n\tconst protocol = decodeURIComponent(\n\t\t(protocol_header && request.headers.get(protocol_header)) || 'https'\n\t);\n\tif (!/^https?$/i.test(protocol)) {\n\t\tthrow new Error(\n\t\t\t`The ${protocol_header} header specified ${protocol} which is an invalid protocol scheme. It should only contain the protocol scheme (e.g. \\`https\\`)`\n\t\t);\n\t}\n\n\tconst host =\n\t\t(host_header && request.headers.get(host_header)) || (request.headers.get('host') ?? url.host);\n\tif (!host) {\n\t\tthrow new Error(\n\t\t\t`Could not determine host from the ${host_header ? `${host_header} or ` : ''}host header`\n\t\t);\n\t}\n\n\tconst port = port_header ? request.headers.get(port_header) : null;\n\tif (port && isNaN(+port)) {\n\t\tthrow new Error(\n\t\t\t`The ${port_header} header specified ${port} which is an invalid port because it is not a number. The value should only contain the port number (e.g. 443)`\n\t\t);\n\t}","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/adapter-bun/src/handler.js#L55-L91","documentation":"When a PROTOCOL_HEADER is configured, adapter-bun derives the request origin's scheme from that header. It only accepts http or https; any other value (or a full URL) is rejected because the header must contain just the protocol scheme.","triggerScenarios":"A reverse proxy sends `Protocol: https://example.com` or `X-Forwarded-Proto: HTTP/1.1` instead of a bare scheme; misconfigured proxy passing the full origin into the protocol header.","commonSituations":"Nginx/Cloudflare misconfiguration where the forwarded proto header includes a host or trailing slash; apps behind proxies that set custom protocol headers with full URLs.","solutions":["Fix the proxy to send only the bare scheme, e.g. nginx: `proxy_set_header X-Forwarded-Proto $scheme;`","Verify the header name matches the PROTOCOL_HEADER env var you configured.","If TLS does not terminate upstream, unset PROTOCOL_HEADER so the default 'https' is used."],"exampleFix":"// nginx before\nproxy_set_header X-Forwarded-Proto $scheme://$host;\n// after\nproxy_set_header X-Forwarded-Proto $scheme;","handlingStrategy":"validation","validationCode":"const proto = (req.headers.get('x-forwarded-proto') || 'https').trim();\nif (!/^https?$/i.test(proto)) throw new Error(`Bad forwarded protocol: ${proto}`);","typeGuard":null,"tryCatchPattern":"try {\n  origin = getOrigin(req);\n} catch (err) {\n  if (/invalid protocol scheme/.test(err.message)) {\n    console.error('Fix proxy to send bare scheme in the protocol header');\n  }\n  throw err;\n}","preventionTips":["Configure proxies with `proxy_set_header X-Forwarded-Proto $scheme;` (bare scheme).","Test behind the real proxy topology, not just locally.","Only set PROTOCOL_HEADER when TLS actually terminates upstream."],"tags":["http-headers","proxy","adapter-bun"],"backgroundTag":"invalid-forwarded-header","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}