redis/redis-py · error · DataError
genpass optionally accepts a bits argument, between 0 and 40
Error message
genpass optionally accepts a bits argument, between 0 and 4096.
What it means
Raised by acl_genpass() as a DataError when the bits argument is supplied but is not coercible to int, or is outside the inclusive range 0..4096. The guard at redis/commands/core.py:202-211 wraps int conversion + range check in a try/except ValueError, re-raising as DataError (a RedisError subclass). The bound matches the Redis server's ACL GENPASS limit.
Source
Thrown at redis/commands/core.py:209
) -> Awaitable[bytes | str]: ...
def acl_genpass(self, bits: int | None = None, **kwargs) -> (
bytes | str
) | Awaitable[bytes | str]:
"""Generate a random password value.
If ``bits`` is supplied then use this number of bits, rounded to
the next multiple of 4.
See: https://redis.io/commands/acl-genpass
"""
pieces = []
if bits is not None:
try:
b = int(bits)
if b < 0 or b > 4096:
raise ValueError
pieces.append(b)
except ValueError:
raise DataError(
"genpass optionally accepts a bits argument, between 0 and 4096."
)
return self.execute_command("ACL GENPASS", *pieces, **kwargs)
@overload
def acl_getuser(
self: SyncClientProtocol, username: str, **kwargs
) -> ACLGetUserData: ...
@overload
def acl_getuser(
self: AsyncClientProtocol, username: str, **kwargs
) -> Awaitable[ACLGetUserData]: ...
def acl_getuser(
self, username: str, **kwargs
) -> ACLGetUserData | Awaitable[ACLGetUserData]:
"""View on GitHub (pinned to da03cdc7e8)
Solutions
- Pass an int in [0, 4096] (or None for the default 256-bit password).
- Validate and clamp the input before calling: bits = max(0, min(4096, int(bits))).
- If accepting user input as a string, confirm it is a clean integer literal before calling acl_genpass.
Example fix
# before
r.acl_genpass(bits=user_input) # user_input='64.0' or 5000
# after
bits = int(user_input)
if not 0 <= bits <= 4096:
raise ValueError('bits must be 0..4096')
r.acl_genpass(bits=bits) Defensive patterns
Strategy: validation
Validate before calling
def valid_bits(bits):
if bits is None:
return None
b = int(bits) # raises ValueError for bad input -> convert to DataError yourself
if not 0 <= b <= 4096:
raise ValueError('bits must be in [0, 4096]')
return b
client.acl_genpass(bits=valid_bits(bits)) Type guard
def is_valid_bits(bits) -> bool:
if bits is None:
return True
try:
return 0 <= int(bits) <= 4096
except (TypeError, ValueError):
return False Try / catch
from redis.exceptions import DataError
try:
client.acl_genpass(bits=bits)
except DataError:
client.acl_genpass(bits=None) # fall back to default Prevention
- Coerce and range-check bits at the input boundary.
- Treat config-sourced values as strings until validated.
When it happens
Trigger: Calling r.acl_genpass(bits) where bits is a non-numeric string, None handled fine (omitted), a float outside range, a negative int, an int > 4096, or something whose int() raises (e.g. 'foo', '16.5', [1]). Note int('16') works, but int('16.5') raises.
Common situations: Reading bits from config/env as a string without conversion; passing a bit count larger than the documented max; copy-paste from a tutorial that uses an outdated limit; off-by-one on a UI slider bound to this value.
Related errors
- ACL LOG count must be an integer
- Invalid slot state: {state}
- Cannot set 'nopass' and supply 'passwords' or 'hashed_passwo
- Password {i} must be prefixed with a "+" to add or a "-" to
- Hashed password {i} must be prefixed with a "+" to add or a
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/83acd170cd8a7e24.json.
Report an issue: GitHub.