A netstring is a tiny, self-describing way to wrap a string so a parser always knows exactly where it ends. Invented by Daniel J. Bernstein, it is widely used in protocols like SCGI and in qmail. This tool encodes any text into a netstring and decodes netstrings back to their payload, all in your browser.
The netstring format
The complete format is described in three characters of grammar: length:data, — where length is the byte count of data expressed in ASCII decimal digits. That is the entire specification.
5:hello, → the string "hello" (5 bytes)
0:, → empty string (0 bytes)
11:hello world, → "hello world" (11 bytes)
No escaping, no quoting, no reserved characters. Because the parser reads exactly length bytes after the colon, the payload can contain any byte value including :, ,, null, and binary data.
How encoding and decoding work
Encoding:
- Measure the input data in UTF-8 bytes using
TextEncoder(not character count — a single emoji is 4 bytes). - Write that count as ASCII decimal digits.
- Append
:, the raw data bytes, then,.
Decoding:
- Read ASCII digits until the first
:. - Parse the digits as the declared byte length.
- Slice exactly that many bytes as the payload.
- Require a
,immediately after. If the comma is missing, the netstring is malformed.
Why bytes, not characters?
The length prefix counts bytes in the UTF-8 encoding, not Unicode codepoints or visible characters. This is critical when the payload contains multi-byte characters:
| String | UTF-8 bytes | Encoded netstring |
|---|---|---|
hello | 5 | 5:hello, |
café | 5 (é is 2 bytes) | 5:café, |
😀 | 4 | 4:😀, |
| (empty) | 0 | 0:, |
Always count bytes, not characters, or the decoder will read the wrong number of bytes and corrupt subsequent messages in a stream.
Where netstrings are used
Netstrings appear in:
- SCGI (Simple Common Gateway Interface): The web-server-to-application protocol used by nginx and others to pass request headers.
- qmail and djbdns: Bernstein’s own mail and DNS tools use them extensively for IPC.
- Length-prefixed messaging in custom protocols: Any situation where you want safe streaming of arbitrary payloads without a framing character that could appear in the data.
Streaming multiple netstrings
You can concatenate netstrings directly without a separator, since each one is self-delimiting:
5:hello,5:world, → two strings: "hello" and "world"
A decoder reads the first length prefix, slices the payload, confirms the comma, then immediately starts the next number — making this suitable for framing messages over a TCP stream or in a file.
When decoding, a prefix that claims a length longer than the remaining data is flagged as an error, so truncated or corrupted streams are detected immediately rather than silently producing garbage.