505 HTTP Version Not Supported: It's Rarely the Version
505 HTTP Version Not Supported: a server refused your HTTP major version. Spot a malformed request line vs a proxy rewrite. Free instant check, no sign-up.
Check your domain for this issue now
Free, no sign-up. Runs the exact check this guide describes and shows what to fix.
Problem
You get 505 HTTP Version Not Supported, and the name sends almost everyone down the wrong road: “my HTTP version is too old, I need to upgrade something.” Nine times out of ten that reading is exactly backwards. RFC 9110 §15.6.6 defines 505 as the response when the server does not support, or refuses to support, the major version of HTTP that was used in the request message. The operative word is major.
That word rules out most of what people suspect. HTTP/1.0 and HTTP/1.1 share the same major version — 1 — so a server that speaks 1.1 will not 505 a 1.0 request; it just answers. HTTP/2 and HTTP/3 aren’t chosen in the request line at all: HTTP/2 is negotiated over TLS with ALPN, HTTP/3 is advertised with Alt-Svc. So a browser essentially cannot talk itself into a 505 through normal version negotiation. When you actually see one, something sent a request line whose version field the server couldn’t accept — and that something is usually a broken request or a hop in the middle, not the browser you’re staring at.
Symptoms
- The status line reads
505 HTTP Version Not Supported; the body is a generic server or proxy error page, not your application’s error format. - It reproduces from a specific client — a script, an SDK, an old device, a scanner — while a normal browser loads the same URL fine.
- It shows up right after you put something new in front of the app: a proxy, a load balancer, an API gateway, a CDN.
- Server logs, if you can read them, show the request line the server actually received — and the version token in it looks wrong.
Top 3 Causes
- A malformed request line - The most common real cause, and it has nothing to do with versions being old. A client that inserts an unencoded space in the target, ends the request line with a bare
\ninstead of\r\n, or writes a non-standard version token makes the server misparse theHTTP-versionfield. Strict servers answer 505; lenient ones answer 400 or just cope. That’s why the same URL is fine in a browser and 505 from a hand-built request. nginx, for instance, deliberately accepts anyHTTP/1.x— so a 505 from an nginx front end usually means the version string wasn’t even a recognizable1.x. - An intermediary that speaks a narrower version - The sneaky case, because your origin is healthy. A reverse proxy, load balancer, or CDN configured to talk HTTP/1.0 upstream — or one that rewrites the version line — can reject the request and return 505 on the origin’s behalf. The request never reaches your app. The tell is the classic split: it works when you hit the origin directly and fails through the public hostname.
- A client pinned to an unsupported major version - The honest case. A legacy or embedded client hard-wired to something the server genuinely won’t serve — HTTP/0.9, or a request line asserting a major version the server disabled — gets a truthful 505. Here the fix is the client: bring it up to HTTP/1.1.
Diagnose with DechoNet
- HTTP Check fetches the URL with a clean, well-formed request and shows you the raw status and response headers. If DechoNet gets a 200 while your client gets 505, you’ve proven the server serves a correct request line fine — the problem is on the sending side or a hop your client’s request touches, not the server itself.
- DNS Check shows whether the hostname resolves to a proxy/CDN or straight to your origin. If it points at an edge network, you’ve found the layer that has its own HTTP version handling to speak with — the prime suspect when the origin works alone but the public URL 505s.
Resolution Checklist
- Capture the exact request line your client sends (proxy it through a debug tool, or read the server access log). Confirm the version token is literally
HTTP/1.1and the line ends in\r\nwith no stray spaces in the target. - Reproduce with a known-good client:
curl -v https://yourdomain.com/path. If curl gets 200 and your client gets 505, the bug is in how your client frames the request — percent-encode the target and fix the line terminator. - Test the origin directly, bypassing any proxy or CDN (origin IP with the right
Hostheader). Origin answers + public URL 505 → an intermediary is rejecting the version. Fix that hop’s HTTP version config (e.g., let the proxy speak HTTP/1.1 upstream). - If a client is pinned to an old major version, upgrade it to HTTP/1.1. Don’t paper over it by making the server accept HTTP/0.9 — that reopens request-smuggling surface you don’t want.
- Don’t confuse this with 426. If the server actually wants you on TLS or HTTP/2, it says so with 426 and an
Upgradeheader. A bare 505 with noUpgradeheader is a refusal, not a redirect to a newer protocol.
When to Escalate
- If the request line is provably correct, no proxy sits in front, and the origin still returns 505, capture the full raw request and response bytes. A 505 from software that clearly supports HTTP/1.1 points at a specific middlebox or WAF rewriting the version field — find the box, not the bug.
- If a managed platform or CDN returns 505 for traffic you can’t reshape (an old partner integration, a fixed device), the fix is that platform’s request-parsing or protocol setting, or a support request on their side — not something you can patch at the origin.
- If you’re tempted to loosen the server to accept malformed or ancient request lines just to silence the error, stop. A server that tolerates sloppy request framing is a server that’s easier to smuggle requests through. Fix the client or the hop that’s sending garbage instead.
Related Tools
Related Guides
Share this guide