redis/redis-py · error · DataError
CLIENT KILL type must be one of
Error message
CLIENT KILL type must be one of {client_types!r} What it means
Raised by Redis.client_kill() when the `_type` argument is supplied but is not one of the allowed client types: 'normal', 'master', 'slave', 'replica', 'pubsub' (case-insensitive via str(_type).lower()). The library validates before building the CLIENT KILL argument list. Other filter fields (_id, addr, laddr, user, maxage, skipme) are not subject to this specific check.
Solutions
- Use one of 'normal', 'master', 'slave', 'replica', 'pubsub' for _type.
- Prefer 'replica' over 'slave' for forward compatibility (both are accepted).
- If you have a custom enum, map it to these canonical names before calling.
Example fix
# before client.client_kill(_type='subscriber') # after client.client_kill(_type='pubsub')
Defensive patterns
Strategy: validation
Validate before calling
VALID_CLIENT_KILL_TYPES = {'normal', 'master', 'slave', 'replica', 'pubsub'}
def safe_client_kill(client, _type=None, **kw):
if _type is not None and str(_type).lower() not in VALID_CLIENT_KILL_TYPES:
raise ValueError(f'_type must be one of {VALID_CLIENT_KILL_TYPES}, got {_type!r}')
return client.client_kill(_type=_type, **kw) Type guard
def is_valid_client_kill_type(_type) -> bool:
return _type is None or (isinstance(_type, str) and _type.lower() in {'normal', 'master', 'slave', 'replica', 'pubsub'}) Try / catch
from redis.exceptions import DataError
try:
client.client_kill(_type=_type)
except DataError as e:
if 'CLIENT KILL type' in str(e):
# map or reject upstream; do not blindly retry
raise ValueError(f'invalid client kill type: {_type}') from e
raise Prevention
- Map your application's client-type enum to Redis's canonical names before calling.
- Prefer 'replica' over 'slave' for forward compatibility.
- Centralize CLIENT KILL usage behind a validated helper.
When it happens
Trigger: Calling client.client_kill(_type='publisher') (invalid), _type='PUBSUB' (valid, case-insensitive), _type='slave' (valid), or _type='replica' (valid). A misspelled or unsupported type like 'pub' or 'subscriber' triggers the error.
Common situations: Mismatched terminology between your app ('publisher','subscriber') and Redis client types; passing a numeric type code instead of the string name; case-sensitivity assumptions (the check lowercases, so casing is fine, but spelling must match).
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
- genpass optionally accepts a bits argument, between 0 and…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/01ea4439cd2150bc.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/core.py:778
) -> int | Awaitable[int]:
"""
Disconnects client(s) using a variety of filter options
:param _id: Kills a client by its unique ID field
:param _type: Kills a client by type where type is one of 'normal',
'master', 'slave', 'replica' or 'pubsub'
:param addr: Kills a client by its 'address:port'
:param skipme: If True, then the client calling the command
will not get killed even if it is identified by one of the filter
options. If skipme is not provided, the server defaults to skipme=True
:param laddr: Kills a client by its 'local (bind) address:port'
:param user: Kills a client for a specific user name
:param maxage: Kills clients that are older than the specified age in seconds
"""
args = []
if _type is not None:
client_types = ("normal", "master", "slave", "replica", "pubsub")
if str(_type).lower() not in client_types:
raise DataError(f"CLIENT KILL type must be one of {client_types!r}")
args.extend((b"TYPE", _type))
if skipme is not None:
if not isinstance(skipme, bool):
raise DataError("CLIENT KILL skipme must be a bool")
if skipme:
args.extend((b"SKIPME", b"YES"))
else:
args.extend((b"SKIPME", b"NO"))
if _id is not None:
args.extend((b"ID", _id))
if addr is not None:
args.extend((b"ADDR", addr))
if laddr is not None:
args.extend((b"LADDR", laddr))
if user is not None:
args.extend((b"USER", user))
if maxage is not None:
args.extend((b"MAXAGE", maxage))View on GitHub (pinned to 6a6b581b48)