sveltejs/kit · error · Error
The ${protocol_header} header specified ${protocol} which is
Error message
The ${protocol_header} header specified ${protocol} which is an invalid protocol scheme. It should only contain the protocol scheme (e.g. `https`) What it means
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.
Source
Thrown at packages/adapter-bun/src/handler.js:73
console.error(
`Could not determine request origin: ${error instanceof Error ? error.message : String(error)}`
);
return new Response('Bad Request', { status: 400 });
}
}
/**
* @param {Request} request
* @param {URL} url
* @returns {string}
*/
function get_origin(request, url) {
// assume TLS terminates upstream, like adapter-node; an http origin would fail CSRF checks
const protocol = decodeURIComponent(
(protocol_header && request.headers.get(protocol_header)) || 'https'
);
if (!/^https?$/i.test(protocol)) {
throw new Error(
`The ${protocol_header} header specified ${protocol} which is an invalid protocol scheme. It should only contain the protocol scheme (e.g. \`https\`)`
);
}
const host =
(host_header && request.headers.get(host_header)) || (request.headers.get('host') ?? url.host);
if (!host) {
throw new Error(
`Could not determine host from the ${host_header ? `${host_header} or ` : ''}host header`
);
}
const port = port_header ? request.headers.get(port_header) : null;
if (port && isNaN(+port)) {
throw new Error(
`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)`
);
}View on GitHub (pinned to 03f1687fe6)
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.
Example fix
// nginx before proxy_set_header X-Forwarded-Proto $scheme://$host; // after proxy_set_header X-Forwarded-Proto $scheme;
Defensive patterns
Strategy: validation
Validate before calling
const proto = (req.headers.get('x-forwarded-proto') || 'https').trim();
if (!/^https?$/i.test(proto)) throw new Error(`Bad forwarded protocol: ${proto}`); Try / catch
try {
origin = getOrigin(req);
} catch (err) {
if (/invalid protocol scheme/.test(err.message)) {
console.error('Fix proxy to send bare scheme in the protocol header');
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not determine host from the ${host_header ? `${host_he
- The ${port_header} header specified ${port} which is an inva
- Address header was specified with ${env_prefix}ADDRESS_HEADE
- ${env_prefix}XFF_DEPTH is ${xff_depth}, but only found ${add
- Cannot build with ${JSON.stringify(file)} because Bun treats
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/79369f45b4af5be6.
Report an issue: GitHub.