redis/redis-py · error · ConnectionError

Invalid RESP version

Error message

Invalid RESP version

What it means

ConnectionError from Connection.on_connect (redis/asyncio/connection.py:975) raised when, after sending HELLO with the requested protocol, the server's reported proto does not match what was requested. This happens when protocol=3 is requested but the server only speaks RESP2 (it ignores/downgrades the HELLO), so the proto field in the response differs. The library refuses to silently run on the wrong protocol.

Solutions

  1. Set protocol=2 if the server/proxy does not support RESP3
  2. Upgrade the Redis server to >= 6.0 for RESP3 support
  3. If behind a proxy, confirm it passes through HELLO negotiation

Example fix

// before
Redis(protocol=3)  # against Redis < 6.0
// after
Redis(protocol=2)
Defensive patterns

Strategy: validation

Validate before calling

# downgrade protocol if server is known to lack RESP3
protocol = 2 if server_version < (6, 0) else 3

Try / catch

try:
    client = Redis(protocol=3)
    await client.ping()
except ConnectionError as e:
    if 'Invalid RESP version' in str(e):
        client = Redis(protocol=2)
        await client.ping()

Prevention

When it happens

Trigger: Connecting with protocol=3 to a Redis server older than 6.0 (no RESP3) or one configured to downgrade; a proxy that strips the HELLO protocol negotiation.

Common situations: Pointing a RESP3-default client at an older Redis; talking to a Redis-compatible proxy (Twemproxy, Envoy, some managed offerings) that does not forward HELLO correctly.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/0556c6fe56a135eb. Report an issue: GitHub.

Appendix: source

Thrown at redis/asyncio/connection.py:976

            # we need to send them via HELLO
        if auth_args and check_protocol_version(self.protocol, 3):
            if isinstance(self._parser, _AsyncRESP2Parser):
                self.set_parser(_AsyncRESP3Parser)
                # update cluster exception classes
                self._parser.EXCEPTION_CLASSES = parser.EXCEPTION_CLASSES
                self._parser.on_connect(self)
            if len(auth_args) == 1:
                auth_args = ["default", auth_args[0]]
            # avoid checking health here -- PING will fail if we try
            # to check the health prior to the AUTH
            await self.send_command(
                "HELLO", self.protocol, "AUTH", *auth_args, check_health=False
            )
            response = await self.read_response()
            if response.get(b"proto") != int(self.protocol) and response.get(
                "proto"
            ) != int(self.protocol):
                raise ConnectionError("Invalid RESP version")
        # avoid checking health here -- PING will fail if we try
        # to check the health prior to the AUTH
        elif auth_args:
            await self.send_command("AUTH", *auth_args, check_health=False)

            try:
                auth_response = await self.read_response()
            except AuthenticationWrongNumberOfArgsError:
                # a username and password were specified but the Redis
                # server seems to be < 6.0.0 which expects a single password
                # arg. retry auth with just the password.
                # https://github.com/andymccurdy/redis-py/issues/1274
                await self.send_command("AUTH", auth_args[-1], check_health=False)
                auth_response = await self.read_response()

            if str_if_bytes(auth_response) != "OK":
                raise AuthenticationError("Invalid Username or Password")

View on GitHub (pinned to 6a6b581b48)