redis/redis-py · error · ConnectionError
protocol must be either 2 or 3
Error message
protocol must be either 2 or 3
What it means
Raised as ConnectionError in Connection.__init__ after successfully parsing protocol as an int, when the value is outside the supported range (p < 2 or p > 3). redis-py supports only RESP2 and RESP3, so any other integer (0, 1, 4, ...) is rejected.
Source
Thrown at redis/asyncio/connection.py:704
self.redis_connect_func = redis_connect_func
self._reader: Optional[asyncio.StreamReader] = None
self._writer: Optional[asyncio.StreamWriter] = None
self._socket_read_size = socket_read_size
self._active_read_timeout = None
self._connect_callbacks: List[weakref.WeakMethod[ConnectCallbackT]] = []
self._buffer_cutoff = 6000
self._re_auth_token: Optional[TokenInterface] = None
self._should_reconnect = False
try:
p = int(protocol)
except TypeError:
p = DEFAULT_RESP_VERSION
except ValueError:
raise ConnectionError("protocol must be an integer")
else:
if p < 2 or p > 3:
raise ConnectionError("protocol must be either 2 or 3")
self.protocol = p
self.legacy_responses = legacy_responses
if parser_class != _AsyncHiredisParser:
# The Python parsers are protocol-specific; hiredis supports both.
if self.protocol == 3 and parser_class == _AsyncRESP2Parser:
parser_class = _AsyncRESP3Parser
elif self.protocol == 2 and parser_class == _AsyncRESP3Parser:
parser_class = _AsyncRESP2Parser
self.set_parser(parser_class)
# HIMPORT client-side state. `himport_registry` is the shared client-level
# registry (empty if unconfigured) and persists across reconnects.
self.himport_registry = himport_registry
self._reset_himport_state()
AsyncMaintNotificationsAbstractConnection.__init__(
self,
maint_notifications_config,View on GitHub (pinned to da03cdc7e8)
Solutions
- Use protocol=2 (RESP2) or protocol=3 (RESP3) — the only supported values.
- Omit the argument to accept the library default (currently RESP3).
- Validate user-supplied config before passing it in (see validationCode).
Example fix
// before client = Redis(url='...', protocol=30) # raises [96] // after client = Redis(url='...', protocol=3)
Defensive patterns
Strategy: validation
Validate before calling
if protocol not in (2, 3):
raise ValueError(f'protocol must be 2 or 3, got {protocol}') Try / catch
from redis.exceptions import ConnectionError
try:
client = Redis(protocol=protocol)
except ConnectionError as e:
if 'protocol must be either 2 or 3' in str(e):
client = Redis(protocol=3) Prevention
- Restrict protocol to {2, 3}.
- Omit the arg to use the library default.
When it happens
Trigger: Passing protocol=1, protocol=4, protocol=0, or a negative int to Redis()/Connection(); a computed protocol value that lands outside 2..3.
Common situations: Typos in config (protocol=30), arithmetic that produces a bad value, or copy-paste from docs that used an unsupported version.
Related errors
- protocol must be an integer
- 'username' and 'password' cannot be passed along with 'crede
- Maintenance notifications are only supported with hiredis an
- Invalid RESP version
- Invalid Database
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/170de481b66b5878.json.
Report an issue: GitHub.