HTTP 505 HTTP Version Not Supported
Quick reference
| Code | 505 |
|---|---|
| Name | HTTP Version Not Supported |
| Category | 5xx Server Error |
| Spec | RFC 9110 §15.6.6 |
| In practice | Rare — version negotiation usually happens at TLS/transport layer |
What 505 means
HTTP 505 HTTP Version Not Supported is returned when the server does not support the major HTTP protocol version the client used in the request. RFC 9110 §15.6.6 states the response should include a description of why the version is not supported and what other protocols are supported.
The HTTP version appears in the request line of HTTP/1.x requests: GET /path HTTP/1.0 or GET /path HTTP/2.0. If a server receives a version number it does not support, it returns 505. The server may also include an Upgrade: header suggesting a supported version, though this is not required.
505 is less common than might be expected because modern protocol version negotiation happens below the HTTP layer. HTTP/2 and HTTP/3 versions are negotiated via TLS ALPN (Application-Layer Protocol Negotiation) during the TLS handshake — the server advertises which HTTP versions it supports, and the client and server agree before any HTTP messages are exchanged. Version mismatches at the ALPN level result in TLS negotiation failures, not 505 responses.
HTTP version history
HTTP/0.9 (1991): The original. Single-line requests with no headers. Only GET. No status codes. The response was just the raw HTML. Never formally standardized.
HTTP/1.0 (RFC 1945, 1996): Added headers, status codes, methods beyond GET, and MIME types. Each request opened a new TCP connection. No keep-alive by default.
HTTP/1.1 (RFC 9110–9112, originally RFC 2068/2616): Persistent connections (keep-alive) by default, chunked transfer encoding, virtual hosting via the mandatory Host: header, range requests, cache-control. Still in widespread use today.
HTTP/2 (RFC 9113, originally RFC 7540, 2015): Binary framing layer, header compression (HPACK), multiplexing (multiple requests on one TCP connection), server push. Negotiated via TLS ALPN with the token h2. Over cleartext uses the Upgrade mechanism (h2c).
HTTP/3 (RFC 9114, 2022): Uses QUIC transport (UDP-based) instead of TCP. Eliminates head-of-line blocking at the transport layer. Negotiated via ALPN with h3, and advertised via the Alt-Svc: response header so clients can switch from HTTP/2 to HTTP/3 on subsequent connections.
When 505 actually appears
HTTP/1.0 requests to HTTP/1.1-only servers: Some strictly-configured servers require the Host: header (mandatory in HTTP/1.1 but absent in HTTP/1.0). A bare HTTP/1.0 request without Host: may get 400 or 505 depending on server policy. nginx and Apache typically return 400 rather than 505 for this case.
Future version numbers: A client sending HTTP/9.0 or any version the server does not recognize will receive 505. This surfaces in security testing when scanners send malformed request lines.
HTTP/2 cleartext (h2c) without upgrade headers: If a client sends raw HTTP/2 binary frames to a server expecting HTTP/1.1 (without the prior Upgrade handshake), the server receives unparseable data and may return 505 or a connection error.
Proxy misconfiguration: A reverse proxy configured to forward HTTP/2 upstream to a backend that only speaks HTTP/1.1 may return 505 when backend HTTP version negotiation fails, though most proxies silently downgrade to HTTP/1.1 instead.
ALPN version negotiation
TLS ALPN (RFC 7301) allows client and server to agree on an application protocol during the TLS handshake. The client sends a list of supported protocols in order of preference. The server selects the highest-priority match and confirms it in the ServerHello. For HTTP, the registered ALPN tokens are:
# ALPN protocol identifiers: h2 → HTTP/2 over TLS http/1.1 → HTTP/1.1 over TLS h3 → HTTP/3 over QUIC # Check which ALPN protocols a server supports: openssl s_client -connect example.com:443 -alpn h2,http/1.1 2>&1 | grep "ALPN" # ALPN protocol: h2 # curl shows the HTTP version used: curl -v https://example.com 2>&1 | grep "HTTP/" # < HTTP/2 200
Because ALPN negotiation happens before any HTTP messages are exchanged, version mismatches at this level do not produce 505. The TLS handshake either succeeds with a mutually supported version or fails with a TLS alert.
505 vs related codes
| Code | Meaning | Difference from 505 |
|---|---|---|
| 505 | HTTP version not supported | — |
| 400 Bad Request | Malformed request | Syntax error; server may understand the version but reject the request |
| 426 Upgrade Required | Must upgrade protocol | Server knows the current version but requires a different one |
| 501 Not Implemented | Method not implemented | The method is unknown; 505 is about the version itself |
Frequently asked questions
Does 505 ever appear in browser developer tools?
Very rarely. Browsers use ALPN to negotiate HTTP versions and match whatever the server supports. A browser would only see 505 if it explicitly sent a version the server rejected — which modern browsers do not do. You might see it in curl testing or custom HTTP clients.
What should the 505 response body say?
RFC 9110 suggests the body should explain why the version is not supported and what protocols the server does support. A minimal example: {"error":"http_version_not_supported","supported":["HTTP/1.1","HTTP/2"]}
Can a CDN return 505?
Yes. Cloudflare, Fastly, and other CDNs proxy requests between client and origin and may return 505 if the origin only supports older HTTP versions and the CDN-to-origin connection negotiation fails. This is more commonly seen as a 502 from the CDN, but 505 is possible if the version mismatch is explicitly detected.
How do I force curl to use HTTP/1.1?
Use the --http1.1 flag: curl --http1.1 https://example.com. To force HTTP/2: curl --http2 https://example.com. To force HTTP/3 (if compiled with QUIC support): curl --http3 https://example.com.
Related guides
HTTP 400 · HTTP 426 · HTTP 501 · HTTP 101 · Cloudflare 520
Server Errors Hub · All Guides · Home