redis/redis-py · error · ConnectionError
protocol must be an integer
Error message
protocol must be an integer
What it means
Raised as a ConnectionError when the 'protocol' argument cannot be parsed as an integer (int(protocol) raises ValueError, e.g. protocol='abc'). Note that None triggers a TypeError which silently falls back to the default RESP version (3), so this error specifically means a non-numeric string/object that int() rejects. The value must be convertible to int.
Source
Thrown at redis/connection.py:926
self.retry.update_supported_errors(self.retry_on_error)
else:
self.retry = Retry(NoBackoff(), 0)
self.health_check_interval = health_check_interval
self.next_health_check = 0
self.redis_connect_func = redis_connect_func
self.encoder = Encoder(encoding, encoding_errors, decode_responses)
self.handshake_metadata = None
self._sock = None
self._socket_read_size = socket_read_size
self._connect_callbacks = []
self._buffer_cutoff = 6000
self._re_auth_token: Optional[TokenInterface] = None
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 self.protocol == 3 and parser_class == _RESP2Parser:
# If the protocol is 3 but the parser is RESP2, change it to RESP3
# This is needed because the parser might be set before the protocol
# or might be provided as a kwarg to the constructor
# We need to react on discrepancy only for RESP2 and RESP3
# as hiredis supports both
parser_class = _RESP3Parser
self.set_parser(parser_class)
self._command_packer = self._construct_command_packer(command_packer)
self._should_reconnect = False
# HIMPORT client-side state. `himport_registry` is the shared client-levelView on GitHub (pinned to da03cdc7e8)
Solutions
- Pass protocol as an integer literal: protocol=2 or protocol=3.
- Sanitize env-var values: protocol=int(os.environ['REDIS_PROTOCOL']) after validating it is numeric.
- Omit protocol to use the default (RESP3).
Example fix
// before r = redis.Redis(protocol='resp3') // after r = redis.Redis(protocol=3)
Defensive patterns
Strategy: validation
Validate before calling
def parse_protocol(raw):
try:
return int(raw)
except (TypeError, ValueError):
raise ValueError(f'protocol must be an integer, got {raw!r}')
protocol = parse_protocol(os.environ.get('REDIS_PROTOCOL', 3)) Try / catch
try:
r = redis.Redis(host=h, protocol=raw_protocol)
except redis.exceptions.ConnectionError as e:
if 'protocol must be an integer' in str(e):
raw_protocol = 3
r = redis.Redis(host=h, protocol=raw_protocol) Prevention
- Coerce and validate protocol to int before passing it to the client.
- Keep REDIS_PROTOCOL env var numeric.
When it happens
Trigger: Passing protocol='three', protocol='resp3', or any non-numeric string to redis.Redis(protocol=...) or the Connection constructor. Reading protocol from an env var that holds a word rather than a digit.
Common situations: Misconfigured REDIS_PROTOCOL environment variable containing a label instead of a number; passing a bool or object that int() rejects; typos in config files.
Related errors
- protocol must be either 2 or 3
- Maintenance notifications handlers on connection are only su
- Maintenance notifications are only supported with RESP versi
- Maintenance notifications handlers on connection are only su
- HELLO is intentionally not implemented in the client.
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/ec53675de88cce77.json.
Report an issue: GitHub.