{"record":{"id":"2bfe0854a6ea56f0","repo":"grpc/grpc-go","slug":"header-key-q-contains-value-with-non-printable-as","errorCode":null,"errorMessage":"header key %q contains value with non-printable ASCII characters","messagePattern":"header key %q contains value with non-printable ASCII characters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/metadata/metadata.go","lineNumber":140,"sourceCode":"\n// ValidatePair validates a key-value pair with the following rules\n// (pseudo-header are skipped):\n//   - the key must contain one or more characters.\n//   - the characters in the key must be in [0-9 a-z _ - .].\n//   - if the key ends with a \"-bin\" suffix, no validation of the corresponding\n//     value is performed.\n//   - the characters in every value must be printable (in [%x20-%x7E]).\nfunc ValidatePair(key string, vals ...string) error {\n\tif err := ValidateKey(key); err != nil {\n\t\treturn err\n\t}\n\tif strings.HasSuffix(key, \"-bin\") {\n\t\treturn nil\n\t}\n\t// check value\n\tfor _, val := range vals {\n\t\tif hasNotPrintable(val) {\n\t\t\treturn fmt.Errorf(\"header key %q contains value with non-printable ASCII characters\", key)\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":122,"sourceCodeEnd":145,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/metadata/metadata.go#L122-L145","documentation":"For non-binary metadata values (key does not end with \"-bin\"), every value must consist solely of printable ASCII characters in the range %x20-%x7E. ValidatePair at metadata.go:138-141 calls hasNotPrintable and rejects values containing bytes below 0x20 (control chars, newline, tab) or above 0x7E. Binary payloads must instead use a \"-bin\" suffixed key so they are base64-encoded.","triggerScenarios":"Triggered when metadata.ValidatePair is called on a non-binary key whose value contains a newline (\\n), tab, NUL, or any byte outside 0x20-0x7E. Common when a developer puts raw bytes (a serialized proto, a UUID with a non-ASCII separator, a value containing a CR/LF) under a normal (non -bin) header key.","commonSituations":"Copying a binary blob (trace context, serialized struct, raw bytes) into a plain metadata value; a value containing a newline or control character from a log/format string; forgetting to base64-encode before attaching as metadata.","solutions":["If the value is binary or may contain non-printable bytes, use a key suffixed with \"-bin\" and attach a base64-encoded value via md.Append(\"my-key-bin\", encodedValue).","If the value is text, strip or escape control characters (newlines, tabs, CR) before insertion.","Validate values with a printable-ASCII check in a helper before adding to metadata."],"exampleFix":"// before:\n//   raw := someBinaryBlob // contains bytes > 0x7E\n//   md := metadata.Pairs(\"payload\", string(raw))\n\n// after:\n//   enc := base64.StdEncoding.EncodeToString(raw)\n//   md := metadata.Pairs(\"payload-bin\", enc)","handlingStrategy":"validation","validationCode":"package main\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n)\n\nfunc printableASCII(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] < 0x20 || s[i] > 0x7E {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc addValue(md map[string][]string, key, val string) error {\n\tif !printableASCII(val) {\n\t\t// force the -bin channel by base64-encoding.\n\t\tenc := base64.StdEncoding.EncodeToString([]byte(val))\n\t\tmd[key+\"-bin\"] = append(md[key+\"-bin\"], enc)\n\t\treturn nil\n\t}\n\tif !printableASCII(key) {\n\t\treturn fmt.Errorf(\"key not printable\")\n\t}\n\tmd[key] = append(md[key], val)\n\treturn nil\n}\n\n// func main() { _ = addValue }","typeGuard":null,"tryCatchPattern":"// Validate values before attaching; if a value may carry non-printable bytes,\n// switch to a '-bin' key.\n//\n//   if err := addValue(md, key, val); err != nil { return err }","preventionTips":["Use '-bin' keys (base64) for any value that may contain non-ASCII bytes.","Strip newlines/CR/tabs from text values before insertion.","Add a printable-ASCII assertion in your metadata-builder tests."],"tags":["metadata","headers","validation","encoding","grpc"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}