redis/redis-py · error · DataError
genpass optionally accepts a bits argument, between 0 and…
Error message
genpass optionally accepts a bits argument, between 0 and 4096.
What it means
Raised by Redis.acl_genpass() when the optional `bits` argument cannot be converted to an integer, or is outside the inclusive range 0..4096. The library catches a ValueError from int() conversion or the explicit range check and re-raises it as a DataError with a descriptive message. This is the same constraint the server enforces for ACL GENPASS.
Solutions
- Ensure `bits` is an int in [0, 4096] before calling; coerce with int(bits) and clamp/validate upstream.
- Omit `bits` entirely to use the server default.
- Validate with a small helper that raises your own configuration error with context.
Example fix
# before
client.acl_genpass(bits=8192)
# after
bits = int(config_bits)
if not 0 <= bits <= 4096:
raise ValueError(f'bits out of range: {bits}')
client.acl_genpass(bits=bits) Defensive patterns
Strategy: validation
Validate before calling
def safe_acl_genpass(client, bits=None):
if bits is not None:
b = int(bits)
if not 0 <= b <= 4096:
raise ValueError(f'bits must be in [0, 4096], got {b}')
return client.acl_genpass(bits=b if bits is None else int(bits)) Type guard
def is_valid_genpass_bits(bits) -> bool:
try:
return 0 <= int(bits) <= 4096
except (TypeError, ValueError):
return False Try / catch
from redis.exceptions import DataError
try:
token = client.acl_genpass(bits=bits)
except DataError as e:
if 'bits argument' in str(e):
token = client.acl_genpass() # fall back to server default
else:
raise Prevention
- Coerce env/config-sourced bit values to int before calling.
- Centralize ACL password generation in a helper that validates the range.
- Omit bits to use the server default rather than guessing.
When it happens
Trigger: Calling client.acl_genpass(bits) where bits is a non-numeric string (e.g. 'random'), None passed via keyword incorrectly, a negative int, an int greater than 4096, or a float like 100.5 (int() truncates but 4097/−1 still fail the range check).
Common situations: Generating ACL passwords programmatically with a user-supplied bit length; passing a config value that was loaded as a string and not coerced to int; assuming default is 256 but supplying 0 expecting 'unlimited'.
Related errors
- ACL LOG count must be an integer
- Cannot set 'nopass' and supply 'passwords' or…
- Category " " must be prefixed with "+" or
- Command " " must be prefixed with "+" or
- Hashed password must be prefixed with a "+" to add or a "-"…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/83acd170cd8a7e24.
Report an issue: GitHub.
Appendix: 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 6a6b581b48)