redis/redis-py · critical · ResponseError

Wrong number of response items from pipeline execution

Error message

Wrong number of response items from pipeline execution

What it means

Raised in `Pipeline._execute_transaction` after EXEC: the number of reply items returned by the server does not match the number of queued commands. This indicates protocol desynchronization — the client and server disagree on how many commands were in the transaction. The connection is forcibly disconnected (the socket is now out of sync) and a ResponseError is raised.

Source

Thrown at redis/client.py:2069

            response = self.parse_response(connection, "_")
        except ExecAbortError:
            if errors:
                raise errors[0][1]
            raise

        # EXEC clears any watched keys
        self.watching = False

        if response is None:
            raise WatchError("Watched variable changed.")

        # put any parse errors into the response
        for i, e in errors:
            response.insert(i, e)

        if len(response) != len(commands):
            self.connection.disconnect()
            raise ResponseError(
                "Wrong number of response items from pipeline execution"
            )

        # find any errors in the response and raise if necessary
        if raise_on_error:
            self.raise_first_error(commands, response)

        # We have to run response callbacks manually
        data = []
        for r, cmd in zip(response, commands):
            if not isinstance(r, Exception):
                args, options = cmd
                # Remove keys entry, it needs only for cache.
                options.pop("keys", None)
                command_name = args[0]
                if command_name in self.response_callbacks:
                    r = self.response_callbacks[command_name](r, **options)
            data.append(r)

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Connect directly to a real Redis node (bypass proxies that may rewrite transaction replies).
  2. Update redis-py and the Redis server to compatible versions; verify RESP2/RESP3 parity.
  3. Remove or audit custom response_callbacks that might reshape EXEC replies.
  4. Report the issue with full command list and server/proxy versions — this is an internal-invariant violation, not a usage error.
Defensive patterns

Strategy: try-catch

Try / catch

from redis.exceptions import ResponseError
try:
    pipe.execute()
except ResponseError as e:
    if 'Wrong number of response items' in str(e):
        # protocol desync — recreate client/pipeline; report bug
        log.error('pipeline reply mismatch: %s', e)
    else:
        raise

Prevention

When it happens

Trigger: Rare corruption of the command stream inside a MULTI/EXEC pipeline: e.g. a command silently produced no response frame (EMPTY_RESPONSE mishandling), a RESP3 push frame was consumed as a reply, or a custom response callback altered the response length. Also seen with parser bugs or non-standard proxies that mangle transaction replies.

Common situations: Using an intermediary (proxy, twemproxy, cluster proxy) that rewrites MULTI/EXEC replies; version skew between redis-py and Redis server; RESP3 push notifications interleaving with transaction replies; custom response_callbacks returning wrong-length data.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/f636f0441187549b.json. Report an issue: GitHub.