redis/node-redis · critical · Error

Unknown RESP type ${type} "${String.fromCharCode(type)}"

Error message

Unknown RESP type ${type} "${String.fromCharCode(type)}"

What it means

Thrown by the RESP3 decoder's top-level dispatch (#decodeTypeValue) when the leading type byte of a reply is not one of the recognized RESP type markers (_, #, :, (, ,, +, $, =, -, !, *, ~, %, >). It means the byte stream the client received does not conform to any RESP type the decoder knows. The message includes the raw byte value and its ASCII rendering to aid diagnosis.

Source

Thrown at packages/client/lib/RESP/decoder.ts:206

        return this.#handleDecodedValue(
          this.onReply,
          this.#decodeSet(this.getTypeMapping(), chunk)
        );

      case RESP_TYPES.MAP:
        return this.#handleDecodedValue(
          this.onReply,
          this.#decodeMap(this.getTypeMapping(), chunk)
        );

      case RESP_TYPES.PUSH:
        return this.#handleDecodedValue(
          this.onPush,
          this.#decodeArray(PUSH_TYPE_MAPPING, chunk)
        );

      default:
        throw new Error(`Unknown RESP type ${type} "${String.fromCharCode(type)}"`);
    }
  }

  #handleDecodedValue(cb, value) {
    if (typeof value === 'function') {
      this.#next = this.#continueDecodeValue.bind(this, cb, value);
      return true;
    }

    cb(value);
    return false;
  }

  #continueDecodeValue(cb, next, chunk) {
    this.#next = undefined;
    return this.#handleDecodedValue(cb, next(chunk));
  }

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Verify the endpoint is actually a Redis (or RESP-speaking) server: `redis-cli -h <host> -p <port> PING`.
  2. Check the TLS setting matches the port: use `rediss://` (or socket.tls=true) only for TLS endpoints, `redis://` for plain.
  3. Inspect the first bytes received from the port (e.g. `openssl s_client` / `nc`) to confirm they start with a RESP type char like `+`, `-`, `$`, `*`, `:`.
  4. Remove or correctly configure any proxy in front of Redis, or switch it to TCP passthrough.
  5. Upgrade the client if the server is a newer Redis emitting a RESP3 type not yet supported by this client version.

Example fix

// before
createClient({ url: 'redis://my-redis:6379' }) // but server requires TLS

// after
createClient({ url: 'rediss://my-redis:6379' })
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.connect();
  await client.ping();
} catch (err) {
  if (err instanceof Error && /Unknown RESP type/.test(err.message)) {
    // the endpoint is not speaking RESP or TLS/plain is mismatched; check the URL scheme and port
  }
  throw err;
}

Prevention

When it happens

Trigger: Connecting to something that is not a Redis/RESP server (e.g. an HTTP endpoint, a MySQL server) on the Redis port; TLS/plain-text mismatch where binary handshake bytes are interpreted as RESP; a proxy/load-balancer injecting a non-RESP banner or error page; severe network corruption truncating the stream mid-frame so the next reply starts on an arbitrary byte.

Common situations: Pointing `redis://` at a `rediss://` (TLS) port or vice-versa; a sidecar/proxy (Envoy, HAProxy in wrong mode) returning a plaintext error; Redis behind a sentinel/cluster router that speaks a different handshake on the same port; ATO/server returning an HTML 502 page; version skew where a server emits an experimental RESP type not in the client's RESP_TYPES table.

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/613035d4c3504556.json. Report an issue: GitHub.