skip to content

You can open a raw TCP connection to Redis with netcat, type `PING` followed by Enter, and get a reply — even though real clients send commands as length-prefixed arrays. What mechanism makes that work, and what are its limitations?

level: juniorimportance: nice to knowfreq 18%

answer

  1. first byte not '*' ⇒ inline: split the line on whitespace
  2. for telnet/nc debugging only
  3. not binary safe; no spaces without quoting
  4. 64KB inline limit → 'Protocol error: too big inline request'
  5. redis-cli is NOT inline — it sends multibulk

basics

~20 s

Redis supports inline commands: if a line does not start with *, the server splits it on whitespace and treats the words as command arguments. It exists for interactive debugging over telnet or netcat. It cannot carry binary or spaces inside arguments, and the line has a length limit, so real clients never use it.

solid answer

~60 s

Redis accepts two request forms. The normal one is a **RESP array of bulk strings** (`*1\r\n$4\r\nPING\r\n`). The fallback is an **inline command**: if the first byte of an incoming line is not `*`, Redis reads up to CRLF and splits the line into arguments on whitespace, honouring simple quoting rules. `PING\r\n` therefore works, and the server replies `+PONG\r\n`. The purpose is stated in the protocol docs: emergency and interactive access when you have only `telnet` or `nc` and no client library — checking liveness, reading `INFO`, running a quick `GET`. Limitations that make it unsuitable for real clients: - **No binary safety.** Arguments are whitespace-delimited text; you cannot pass arbitrary bytes, embedded newlines, or reliably pass values with spaces. - **Length limited.** The inline request buffer is bounded (64KB in the implementation), and an over-long line yields `Protocol error: too big inline request`. - **Ambiguity.** A malformed multibulk line can be misread as inline, producing confusing `Protocol error: unbalanced quotes` style errors. So it is a debugging affordance, not an API.

code

text · 17 lines
text
$ nc redis-host 6379
PING
+PONG
INFO server
$3421
# Server
redis_version:7.2.4
...

# what a normal client sends instead (multibulk / RESP array):
*1\r\n$4\r\nPING\r\n

# an HTTP probe pointed at 6379 falls into the inline path:
GET / HTTP/1.1
-ERR unknown command 'GET / HTTP/1.1' ...
# and an over-long line:
-ERR Protocol error: too big inline request

go deeper

for a junior

Know that typing a plain command line over telnet or netcat works because Redis accepts inline commands, and that it is only for quick manual checks.

for a middle

Explain the first-byte dispatch between inline and multibulk, and the binary-safety and size limitations that keep clients on multibulk.

for a senior

Use it diagnostically: prove reachability through firewalls and proxies, and recognise too big inline request in logs as non-RESP traffic hitting the port, which can also be an exposure signal.

for a principal

Frame it as a deliberate operability affordance with a bounded blast radius — cheap human access without weakening the real protocol — and note the operational hygiene it implies about who can reach the port at all.

## Two request formats When Redis reads from a client socket it inspects the first byte of the pending request: - If it is `*`, the request is parsed as a **multibulk** (RESP array) request: an element count, then that many `$<len>\r\n<bytes>\r\n` bulk strings. This is what every client library sends. - If it is anything else, the request is treated as an **inline command**: read bytes until CRLF (or LF), then split the resulting line into arguments. That is the whole mechanism. There is no handshake and no mode switch — it is decided per request, by the first byte. ## Why it exists The protocol documentation is explicit: inline commands exist so you can send commands when you do not have a client library at hand — the classic case being `telnet` or `nc` to a server during an incident. Typing `PING` and getting `+PONG` proves the server is alive and reachable through whatever firewall, proxy, or TLS terminator sits between you and it. `INFO`, `CONFIG GET maxmemory`, `DBSIZE`, and a quick `GET key` are all reachable this way. It also means a health check can be as crude as a TCP connect plus writing `PING\r\n` — no Redis library needed in the checker. ## The parsing rules The line is split on whitespace with `sdssplitargs`-style rules, which support simple quoting: `SET greeting "hello world"` works, and `"\x41"` style escapes inside double quotes are honoured to a limited degree. But the model is fundamentally "a shell-ish line", not "a byte-exact argument vector". ## Limitations **Not binary safe.** There is no length prefix, so an argument cannot contain a raw newline, and anything with spaces depends on quoting the server-side splitter must interpret. A JPEG or a protobuf simply cannot be sent this way. This alone disqualifies it for client libraries, since Redis's headline property is binary-safe keys and values. **Bounded length.** The inline buffer is limited (64KB in the implementation). Exceed it and the server replies with a protocol error and closes the connection: `-ERR Protocol error: too big inline request`. Multibulk requests have their own, much larger limits (`proto-max-bulk-len`, default 512MB per bulk). **Error modes are confusing.** Because the format is chosen by the first byte, a client that emits a malformed multibulk request — say, a stray leading byte before `*` — has its data reinterpreted as inline text, producing errors like `Protocol error: unbalanced quotes in request` or `expected '$', got ...`. Debugging a broken client often means recognising that the server fell into the inline path. **No pipelining discipline.** You can type several lines, and each is a separate inline request, but there is no framing to help a tool match replies to requests beyond ordering. **Interactive tools mislead.** `redis-cli` looks like it is typing inline commands, but it is a real client and sends multibulk. Do not cite `redis-cli` as evidence about inline behaviour. ## When you will actually meet it 1. **Liveness checks** — a load balancer or a shell one-liner writing `PING\r\n`. 2. **Firewall/TLS path debugging** — proving the port is reachable and speaks Redis before blaming the application. (Note: against a TLS-enabled port you need `openssl s_client` rather than plain `nc`.) 3. **Reading protocol errors in logs** — recognising that `too big inline request` almost always means something wrote non-RESP bytes to the port: an HTTP request from a misconfigured probe, a port scanner, or an application pointing an HTTP client at 6379. That last case is worth knowing as a security signal too, since it is how cross-protocol probing of an exposed Redis shows up. ## The one-sentence takeaway Inline commands are a convenience path for humans with a raw socket; every real client sends multibulk arrays, because only length-prefixed bulk strings can carry arbitrary bytes.

  • Why can't a client library use inline commands as its normal transport?
    Because arguments are whitespace-delimited text with no length prefix, so they cannot carry arbitrary bytes — embedded newlines are impossible and values containing spaces depend on quoting rules the server-side splitter must interpret. Redis's core promise is binary-safe keys and values, which only length-prefixed bulk strings deliver. The inline request buffer is also capped at 64KB, far below the multibulk limits.
  • Your Redis log shows repeated `Protocol error: too big inline request` entries. What is likely happening?
    Something is writing non-RESP bytes to the Redis port, so the parser sees a first byte other than `*` and falls into the inline path, then overruns the 64KB inline buffer. Common causes are an HTTP client or health probe misconfigured to point at 6379, a load balancer speaking the wrong protocol, or an internet-exposed instance being probed by a scanner. Investigate the source addresses, and treat exposure to untrusted networks as a security issue in its own right.

saying these in an interview costs you the question

  • Believing redis-cli sends inline commands rather than RESP arrays
  • Thinking inline commands are the standard protocol and multibulk is an optimisation
  • Assuming values with spaces or binary content can be sent inline
  • Not knowing there is a size limit, and being puzzled by 'too big inline request' errors
  • Recommending inline commands for application code because they are simpler

context