What rules govern a custom gRPC metadata key and its value, and where on a call may it travel?
answer
- beside the message, not inside it
- keys are lowercase and narrowly charset-limited
- grpc- is the protocol's own namespace
- printable ASCII values, or -bin base64
- client sends metadata only at call start
basics
~10 sKeys are lowercase and drawn from digits, a-z, underscore, hyphen and dot; the grpc- prefix is reserved. Plain values are printable ASCII only, so binary needs a key ending -bin whose value is base64.
solid answer
~40 sCustom metadata is key-value data that rides **beside** the request and response messages rather than inside them. A key uses only digits, `a-z`, `_`, `-` and `.`, and is **lowercase**; keys beginning `grpc-` are reserved for the protocol itself. An ordinary value must be **printable ASCII**, so anything else — raw bytes, non-ASCII text — needs a key whose name ends in **`-bin`**, whose value is then base64-encoded on the wire and decoded back to bytes for you. Values are not constrained to lowercase; only keys are. A client sends metadata **only as request headers**. A server may send **leading** metadata before its messages and **trailing** metadata after them, and the same key may appear more than once.
code
http · 7 lines:path /pharmacy.v1.Eligibility/CheckPrescription
te: trailers
content-type: application/grpc+proto
grpc-timeout: 800m
counter-id: STORE-4417
dispensing-pharmacist: 4417-KL
request-trace-bin: AAAAAAAAAAAAAAAAAAAAAQ==go deeper
Know that metadata is key-value data travelling beside the request and response messages, and that keys are lowercase with a restricted character set. Recognising one in a request capture is enough.
Explain the rules: the reserved grpc- namespace, printable-ASCII values, the -bin suffix that marks a base64 binary value, and the fact that a client sends metadata only as request headers while a server has both leading and trailing.
Defend the boundary in a design review — what belongs in the schema versus the envelope — and know that repeated keys keep their relative order while order across different keys does not.
Metadata is where cross-cutting conventions ossify across teams. Decide which keys are organisation-wide, who may mint one, and how a key is retired once callers depend on it.
## Metadata is the envelope, not the letter A gRPC call carries two separate channels of information. The **messages** are the schema-defined payload — the prescription id, the eligibility answer. **Metadata** is a list of key-value pairs travelling alongside them, outside the schema: a counter identifier, a correlation key, a credential, a locale. The practical consequence is that metadata is readable without understanding the service. Code that never parses the message can still read a metadata key, which is why cross-cutting concerns live there and business data does not. ## The key rules - A key is built from **digits, `a-z`, `_`, `-` and `.`** — and it is **lowercase**. There is no uppercase form on the wire; a library that lets you write `Counter-Id` is lowercasing it for you. - Keys starting with **`grpc-`** are **reserved for the protocol**. `grpc-timeout`, `grpc-status`, `grpc-message`, `grpc-encoding` and their siblings are protocol fields, and an application key in that namespace risks colliding with a field the transport interprets. - A key ending in **`-bin`** is special, and the suffix is part of the name on the wire. ## Values: printable ASCII, or base64 An ordinary metadata value is limited to **printable ASCII** — the range from space through `~`. That rules out raw bytes, control characters, and any non-ASCII text such as an accented name. The escape hatch is the **`-bin` suffix**. When a key ends in `-bin`, its value is **base64** on the wire and the receiving library hands you the decoded bytes. Two details matter: 1. The base64 form is what the wire carries, so the field is roughly **four bytes for every three** of your data — about a third larger than the raw value. 2. Implementations are required to accept both padded and unpadded base64, so a trailing `=` may or may not be present on a value you receive. Note the asymmetry that catches people: **keys are lowercase, values are not**. `counter-id: STORE-4417` is entirely legal — the uppercase is in the value, which only has to be printable ASCII. ## Where metadata may travel | direction | where | when | |---|---|---| | client to server | request metadata (headers) | once, before the request message | | server to client | leading metadata | before the server's first message | | server to client | trailing metadata | after the last message, with the call's outcome | The asymmetry is real and worth stating plainly: **a client sends metadata only at the start of a call**. There is no client-side trailing metadata to send after its messages. The server has both openings, and when it fails before sending anything at all it may send a single block that serves as both. ## Duplicates, order and size - The **same key may appear more than once**. Repeated entries keep their **relative order**, so a list sent under one key arrives in the order it was sent. - Repeated entries may equivalently be carried as **one comma-joined value**; a receiver has to cope with either shape. - Order **between different keys** is not guaranteed, so never encode meaning in the position of one key relative to another. - The block is **size-bounded** in practice, so metadata is for small facts. Bulk belongs in the message, where the schema describes it and the size limits are the message's. ## The judgment part The question 'should this be metadata or a message field?' has a reliable test: **if the service's contract needs it to answer the call, it is a message field**. A prescription id is part of the request. A correlation key that lets an operator find this call in a log later is metadata — nothing in the eligibility logic reads it, and the service would still work if it were absent. Putting business data in metadata hides it from the schema, from versioning and from anyone reading the `.proto` to learn what the call takes.
- A gRPC metadata value must hold sixteen raw bytes. What does the key have to look like?It must end in `-bin`, for example `request-trace-bin`. The library base64-encodes the bytes for the wire and decodes them on arrival, because an ordinary metadata value is limited to printable ASCII and cannot carry arbitrary bytes at all.
- Can a gRPC client send trailing metadata after its request messages?No. The client's metadata goes out once, as request headers at the start of the call. Leading and trailing metadata are the server's to send — leading before its first message, trailing after its last, carrying the call's outcome.
- Why should a prescription id never be carried as gRPC metadata?Because the service needs it to answer the call, which makes it part of the contract. Message fields are described by the schema, versioned with it and visible to anyone reading it; metadata is none of those things and is meant for facts the service's logic does not read.
Metadata is what is written on the envelope; the request message is the letter inside. Anything handling the post can read the envelope without opening the letter.
saying these in an interview costs you the question
- Thinks a metadata key may be mixed case on the wire
- Believes metadata values must also be lowercase
- Uses a grpc- prefix for an application key
- Puts raw bytes in a plain key's value
- Thinks the -bin suffix is stripped before the wire
- Carries schema-worthy business data as metadata