redis/redis-rb · error

Redis: the server does not support RESP3 (the HELLO 3 handsh

Error message

Redis: the server does not support RESP3 (the HELLO 3 handshake failed); falling back to RESP2. Pass `protocol: 2` to select RESP2 explicitly and silence this warning.

What it means

Error "Redis: the server does not support RESP3 (the HELLO 3 handshake failed); falling back to RESP2. Pass `protocol: 2` to select RESP2 explicitly and silence this warning." thrown in redis/redis-rb.

Source

Thrown at lib/redis.rb:291

  # cluster via Redis::Cluster::Client#handle_errors. Because every @client access — single commands,
  # pipelined, multi, watch, and the pub/sub socket — flows through #synchronize, wrapping it here
  # covers them all.
  #
  # Must be called while holding @monitor: it closes and replaces @client, so it has to be
  # serialized with the command execution that uses @client. The retried block re-reads @client, so
  # callers must reference the rebuilt instance (via the synchronize block argument), not a cached
  # one.
  def with_protocol_fallback
    yield
  rescue ::RedisClient::Error => error
    if @options.fetch(:protocol, 3).to_i == 3 && Client.resp3_unsupported?(error)
      @options = @options.merge(protocol: 2)
      @client.close
      @client = build_client
      # Warn only once the RESP2 client is actually in place — if the rebuild itself raises we
      # haven't really fallen back. Fires once per client: @options[:protocol] is now 2, so this
      # branch never re-enters. Passing `protocol: 2` explicitly skips it (and silences this).
      warn("Redis: the server does not support RESP3 (the HELLO 3 handshake failed); falling back " \
           "to RESP2. Pass `protocol: 2` to select RESP2 explicitly and silence this warning.")
      retry
    end

    raise
  end

  def _subscription(method, timeout, channels, block)
    if block
      if @subscription_client
        raise SubscriptionError, "This client is already subscribed"
      end

      begin
        # The pub/sub second socket is opened via @client.pubsub, which connects through
        # ensure_connected rather than a command path. Route it through #synchronize so the same
        # RESP3->RESP2 fallback applies when subscribe is the first operation against an old server.
        @subscription_client = SubscribedClient.new(synchronize(&:pubsub))

View on GitHub (pinned to 2ba9010b91)

Solutions

  1. Pass protocol: 2 to Redis.new to select RESP2 explicitly and silence the fallback warning.
  2. Upgrade the server to Redis 6.0 or newer to get native RESP3 support.

When it happens

Trigger: Thrown at lib/redis.rb:291 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of redis/redis-rb@2ba9010b91 (2026-08-23). Data as JSON: /api/errors/9e6fc691665bb804. Report an issue: GitHub.