redis/redis-py · error · ConnectionError
Invalid RESP version
Error message
Invalid RESP version
What it means
Raised in on_connect (connection.py:1187-1191) on the RESP3 path when HELLO succeeds (no auth case) but the returned handshake 'proto' field does not equal the requested protocol. The server claimed to negotiate HELLO 3 but reported a different proto number in its reply, indicating the server did not actually switch to the requested RESP version. Treated as a connection failure.
Solutions
- Bypass the proxy and connect directly to a Redis node to confirm RESP3 works there.
- Fall back to protocol=2 if the intermediary cannot carry RESP3 correctly.
- Upgrade the proxy/middleware to one that transparently forwards HELLO.
- Upgrade Redis to a version with correct HELLO/proto reporting.
Example fix
# before r = redis.Redis(host='proxy', port=6379, protocol=3) # after r = redis.Redis(host='redis-node-0', port=6379, protocol=3)
Defensive patterns
Strategy: fallback
Validate before calling
# Detect a non-conforming intermediary before relying on RESP3
def negotiate_protocol(host, port):
r = redis.Redis(host=host, port=port, protocol=3)
try:
r.ping()
return 3
except redis.exceptions.ConnectionError as e:
if 'Invalid RESP version' in str(e):
return 2 # proxy can't carry RESP3
raise
r = redis.Redis(host=h, port=p, protocol=negotiate_protocol(h, p)) Type guard
null
Try / catch
from redis.exceptions import ConnectionError
try:
r = redis.Redis(host=h, port=p, protocol=3)
r.ping()
except ConnectionError as e:
if 'Invalid RESP version' in str(e):
r = redis.Redis(host=h, port=p, protocol=2) # fallback
else:
raise Prevention
- Test RESP3 against the real endpoint (through any proxy) before standardising on protocol=3.
- Keep a protocol=2 fallback in config for misbehaving proxies.
- Upgrade proxy/middleware that mangles HELLO responses.
When it happens
Trigger: Connecting with protocol=3 to a server that accepts HELLO but echoes back a different proto (misbehaving proxy, RESP3-incompatible middleware, or a server that silently downgrades); a man-in-the-middle/transparent proxy rewriting HELLO responses.
Common situations: HAProxy/Envoy/Nginx in front of Redis that doesn't forward HELLO correctly; Redis versions with RESP3 bugs; connecting through a sharding proxy that strips HELLO metadata.
Related errors
- Bad response from PING health check
- Invalid RESP version
- A non health check response was cleaned by execute_command
- Cannot retrieve information about server version
- Client caching is only supported with RESP version 3
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/94cf415663e7716f.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:1191
auth_response = self.read_response()
if str_if_bytes(auth_response) != "OK":
raise AuthenticationError("Invalid Username or Password")
# if resp version is specified, switch to it
elif check_protocol_version(self.protocol, 3):
if isinstance(self._parser, _RESP2Parser):
self.set_parser(_RESP3Parser)
# update cluster exception classes
self._parser.EXCEPTION_CLASSES = parser.EXCEPTION_CLASSES
self._parser.on_connect(self)
self.send_command("HELLO", self.protocol, check_health=check_health)
self.handshake_metadata = self.read_response()
if (
self.handshake_metadata.get(b"proto") != self.protocol
and self.handshake_metadata.get("proto") != self.protocol
):
raise ConnectionError("Invalid RESP version")
# Activate maintenance notifications for this connection
# if enabled in the configuration
# This is a no-op if maintenance notifications are not enabled
self.activate_maint_notifications_handling_if_enabled(check_health=check_health)
# if a client_name is given, set it
if self.client_name:
self.send_command(
"CLIENT",
"SETNAME",
self.client_name,
check_health=check_health,
)
if str_if_bytes(self.read_response()) != "OK":
raise ConnectionError("Error setting client name")
# Set the library name and version from driver_infoView on GitHub (pinned to 6a6b581b48)