redis/redis-py · error · RedisError

Client caching is only supported with RESP version 3

Error message

Client caching is only supported with RESP version 3

What it means

Raised by RedisCluster.__init__ when client-side caching (cache_config or cache) is enabled but the negotiated RESP protocol version is not 3. Server-assisted client-side caching (push messages, cache invalidation) requires the RESP3 protocol, so the constructor rejects the combination eagerly at cluster.py:886.

Solutions

  1. Set protocol=3 when enabling caching: RedisCluster(host=..., protocol=3, cache_config=...).
  2. Verify no global default forces protocol=2 in your config.
  3. Drop cache_config/cache if you cannot use RESP3 in your deployment.

Example fix

// before
client = RedisCluster(host='localhost', port=7000, cache_config=CacheConfig())  # RedisError

// after
client = RedisCluster(host='localhost', port=7000, protocol=3, cache_config=CacheConfig())
Defensive patterns

Strategy: validation

Validate before calling

from redis._parsers.helpers import check_protocol_version
protocol = kwargs.get('protocol')
if (cache_config or cache) and not check_protocol_version(protocol, 3):
    kwargs['protocol'] = 3  # or drop cache_config
client = RedisCluster(host='localhost', port=7000, protocol=kwargs.get('protocol', 3), cache_config=cache_config)

Type guard

def cache_config_is_resp3_compatible(kwargs, cache_config, cache) -> bool:
    from redis._parsers.helpers import check_protocol_version
    return not (cache_config or cache) or check_protocol_version(kwargs.get('protocol'), 3)

Try / catch

from redis.exceptions import RedisError
try:
    client = RedisCluster(host='localhost', port=7000, cache_config=cache_config)
except RedisError as e:
    if 'RESP version 3' in str(e):
        client = RedisCluster(host='localhost', port=7000, protocol=3, cache_config=cache_config)
    else:
        raise

Prevention

When it happens

Trigger: RedisCluster(host=..., cache_config=CacheConfig(...)) or RedisCluster(host=..., cache=Cache(...)) without setting protocol=3 (or with protocol=2 / default-less config that resolves to RESP2).

Common situations: Enabling the cache without upgrading the wire protocol; sharing config between standalone (protocol may default differently) and cluster clients; assuming the default protocol is RESP3 when it resolves to RESP2 in your environment.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/9759ac8db246591d. Report an issue: GitHub.

Appendix: source

Thrown at redis/cluster.py:887

        kwargs = cleanup_kwargs(**kwargs)
        if retry:
            self.retry = retry
        else:
            self.retry = Retry(
                backoff=ExponentialWithJitterBackoff(
                    base=DEFAULT_RETRY_BASE, cap=DEFAULT_RETRY_CAP
                ),
                retries=cluster_error_retry_attempts,
            )

        self.encoder = Encoder(
            kwargs.get("encoding", "utf-8"),
            kwargs.get("encoding_errors", "strict"),
            kwargs.get("decode_responses", False),
        )
        protocol = kwargs.get("protocol", None)
        if (cache_config or cache) and not check_protocol_version(protocol, 3):
            raise RedisError("Client caching is only supported with RESP version 3")

        if (
            maint_notifications_config
            and maint_notifications_config.enabled
            and not check_protocol_version(protocol, 3)
        ):
            raise RedisError(
                "Maintenance notifications are only supported with RESP version 3"
            )
        if check_protocol_version(protocol, 3) and maint_notifications_config is None:
            maint_notifications_config = MaintNotificationsConfig()

        # Build the client-level HIMPORT registry once (always empty at construction)
        # and share the same object with every node pool, so the fieldset registry is
        # shared cluster-wide and runtime himport_prepare mutates one object. It is
        # handed to the NodesManager and injected onto each node's pool in
        # create_redis_node; it is deliberately NOT forwarded through connection_kwargs,
        # so nodes reuse the one shared object rather than each rebuilding their own.

View on GitHub (pinned to 6a6b581b48)