Skip to main content
505

HTTP Version Not Supported

Active
RFC 9110 §15.6.6Since 1997Legacy servers, protocol gateways, malformed request handling

HTTP 505 HTTP Version Not Supported indicates the server does not support the major version of HTTP used in the request. Defined in RFC 9110 §15.6.6. The response SHOULD explain why that version is unsupported and list supported protocols. Rare in practice — most servers handle HTTP/1.0 through HTTP/3.

Description

The 505 HTTP Version Not Supported status code indicates that the server does not support, or refuses to support, the major version of HTTP that was used in the request message. The server is indicating that it is unable or unwilling to complete the request using the same major version as the client.

The server SHOULD generate a representation for the 505 response that describes why that version is not supported and what other protocols are supported by that server. This gives the client enough information to retry with a compatible version or connect through a different mechanism entirely.

505 is fundamentally different from 426 Upgrade Required. A 505 means the server cannot speak your HTTP version at all — it doesn't understand the wire format of your request. A 426 means the server understands your HTTP version fine but wants you to switch to a different application-layer protocol (like upgrading from HTTP/1.1 to WebSocket). The distinction: 505 is about the transport envelope, 426 is about the application protocol inside it.

In modern infrastructure, 505 is exceptionally rare. Most production servers and reverse proxies support HTTP/1.0, HTTP/1.1, HTTP/2, and HTTP/3 simultaneously. You're most likely to encounter it in edge cases: a client sending HTTP/0.9 (which has no headers at all) to a modern server, a bleeding-edge HTTP/3-only client hitting a legacy server, or a malformed request line that a server interprets as an unrecognized protocol version.

Some servers also return 505 when they receive a syntactically valid but semantically nonsensical version string — like HTTP/4.0 or HTTP/99.9 — since there's no way to negotiate a downgrade for a version that doesn't exist yet.

Examples

Client sends HTTP/0.9 request to a modern server
http
GET /index.html

(Note: HTTP/0.9 has no version string, no headers, just a bare GET line)
505 response — version not supported
http
HTTP/1.1 505 HTTP Version Not Supported
Content-Type: application/json

{"error": "http_version_not_supported", "message": "This server does not support HTTP/0.9 requests.", "supported_versions": ["HTTP/1.0", "HTTP/1.1", "HTTP/2"], "documentation": "https://example.com/docs/supported-protocols"}
Client sends unrecognized HTTP version
http
GET /api/data HTTP/4.0
Host: api.example.com
Accept: application/json
505 response — unknown version string
http
HTTP/1.1 505 HTTP Version Not Supported
Content-Type: application/json
Connection: close

{"error": "unsupported_http_version", "message": "HTTP/4.0 is not recognized. This server supports HTTP/1.0, HTTP/1.1, and HTTP/2.", "requested_version": "4.0", "supported_versions": ["1.0", "1.1", "2"]}
HTTP/3 request to a server that only supports HTTP/1.1
http
GET /resource HTTP/3
Host: legacy.example.com
:method: GET
:path: /resource
505 from legacy server — only knows HTTP/1.1
http
HTTP/1.1 505 HTTP Version Not Supported
Content-Type: text/plain
Connection: close

This server only supports HTTP/1.1. Please downgrade your client or use a compatible proxy.

Edge Cases

  • 505 is about the MAJOR version of HTTP — a server that supports HTTP/1.1 should also handle HTTP/1.0 requests (same major version). The RFC says 'major version' but in practice servers may reject minor version mismatches too.
  • HTTP/0.9 requests have no version string at all (just 'GET /path\r\n'). A server that doesn't recognize this bare format may return 505 or simply close the connection without a response.
  • Some servers return 400 Bad Request instead of 505 when the version string is malformed (e.g., 'HTTP/abc'). Technically 505 is more appropriate if the server interprets it as an unsupported version rather than a syntax error.
  • Behind a reverse proxy (nginx, HAProxy), the upstream server may never see the original HTTP version — the proxy normalizes to HTTP/1.1 internally. A 505 from the proxy itself means it couldn't parse the client's request.
  • HTTP/2 and HTTP/3 use binary framing and ALPN negotiation — version mismatch is typically handled at the TLS layer before the server ever generates an HTTP response. A 505 response implies text-based HTTP (1.x) parsing.
  • Load balancers that terminate HTTP/2 and proxy as HTTP/1.1 will never pass HTTP/2 framing to backends, so backends that only speak HTTP/1.1 won't encounter version issues in this architecture.
  • A server returning 505 SHOULD use a version it does support in the response status line — typically HTTP/1.1, since the client clearly didn't negotiate HTTP/2 or HTTP/3 successfully.

When You'll See This

  • A client library hardcoded to send HTTP/0.9 requests hits a modern API server that requires at least HTTP/1.0
  • Penetration testing tool sends crafted requests with fake version strings (HTTP/9.9) to probe server behavior
  • Legacy embedded device firmware sends HTTP/1.0 to a server configured to require HTTP/1.1 minimum
  • Misconfigured proxy sends raw HTTP/2 binary frames to a backend that only parses HTTP/1.1 text
  • Automated scanner sends malformed request lines that the server interprets as an unrecognized HTTP version
  • IoT device with outdated HTTP stack attempts to connect to a cloud endpoint that has deprecated HTTP/1.0 support
  • Development server configured with strict version checking rejects requests from a client using an experimental HTTP draft version

Implementation References

LanguageConstant
Gohttp.StatusHTTPVersionNotSupported
Rusthttp::StatusCode::HTTP_VERSION_NOT_SUPPORTED
Pythonhttp.HTTPStatus.HTTP_VERSION_NOT_SUPPORTED
Node.jshttp.STATUS_CODES[505]
.NETHttpStatusCode.HttpVersionNotSupported
JavaHttpURLConnection.HTTP_VERSION
PHPResponse::HTTP_VERSION_NOT_SUPPORTED (Symfony)
Ruby:http_version_not_supported (Rack)

History

Introduced in HTTP/1.1 (RFC 2068, January 1997) alongside the formalization of protocol versioning. The original motivation was forward-compatibility: as HTTP evolved beyond 1.1, servers needed a way to signal that they couldn't process newer versions. Carried forward unchanged through RFC 2616 (1999) and RFC 7231 (2014), and now lives in RFC 9110 (2022). In practice, the code became nearly obsolete as HTTP/2 (2015) introduced ALPN-based version negotiation at the TLS layer, making version mismatches a connection-level failure rather than an HTTP-response-level one. HTTP/3 (2022) further reduced its relevance by using QUIC, where version negotiation happens before any HTTP framing.

Related Status Codes

Related Headers

FAQ

What is the difference between 505 HTTP Version Not Supported and 426 Upgrade Required?

505 means the server cannot process your request because it doesn't support the HTTP protocol version you used — it literally cannot parse or understand the wire format. 426 means the server understands your HTTP version perfectly fine but requires you to switch to a different application-level protocol (like WebSocket or TLS). Think of 505 as 'I don't speak your language at all' versus 426 as 'I understand you, but we need to move this conversation to a different channel.' A server returning 426 includes an Upgrade header telling you which protocol to use; a server returning 505 tells you which HTTP versions it supports.

Why is 505 so rare in production environments?

Three reasons. First, most production web servers (nginx, Apache, Caddy, IIS) and cloud load balancers support HTTP/1.0, HTTP/1.1, and HTTP/2 simultaneously — there's simply no version mismatch to trigger. Second, HTTP/2 and HTTP/3 use ALPN (Application-Layer Protocol Negotiation) during the TLS handshake to agree on a version before any HTTP traffic flows — if the server doesn't support HTTP/2, the connection falls back to HTTP/1.1 at the TLS layer, never reaching the point where a 505 would be generated. Third, reverse proxies typically normalize all incoming traffic to HTTP/1.1 when forwarding to backends, hiding version differences entirely.

How should a server respond when it receives an HTTP version it doesn't support?

Per RFC 9110, the server SHOULD generate a response that describes why the version is not supported and what protocols the server does support. In practice this means: (1) respond using a version the server does support (typically HTTP/1.1 in the status line), (2) include a response body listing supported versions and ideally a link to documentation, (3) consider including a Connection: close header since further communication on this connection is unlikely to succeed, and (4) log the event for monitoring since repeated 505s may indicate a misconfigured client or a protocol negotiation failure in your infrastructure.