{"record":{"id":"45a2b3c50c677893","repo":"nats-io/nats-server","slug":"invalid-utf8-for-s-q","errorCode":null,"errorMessage":"invalid utf8 for %s %q","messagePattern":"invalid utf8 for (.+?) %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mqtt.go","lineNumber":4329,"sourceCode":"\tif payloadSize < 0 {\n\t\treturn fmt.Errorf(\"invalid remaining length %d for PUBLISH packet\", pl)\n\t}\n\tpp.sz = payloadSize\n\tif pp.sz > 0 {\n\t\tstart = r.pos\n\t\tr.pos += pp.sz\n\t\tpp.msg = r.buf[start:r.pos]\n\t} else if pp.sz == 0 {\n\t\tpp.msg = nil\n\t} else {\n\t\treturn errMQTTInvalidPublishLength\n\t}\n\treturn nil\n}\n\nfunc mqttValidateTopic(topic []byte, field string) error {\n\tif !utf8.Valid(topic) {\n\t\treturn fmt.Errorf(\"invalid utf8 for %s %q\", field, topic)\n\t}\n\tif bytes.IndexByte(topic, 0) >= 0 {\n\t\treturn fmt.Errorf(\"invalid null character in %s %q\", field, topic)\n\t}\n\treturn nil\n}\n\nfunc mqttValidateString(value string, field string) error {\n\tif !utf8.ValidString(value) {\n\t\treturn fmt.Errorf(\"invalid utf8 for %s %q\", field, value)\n\t}\n\tif strings.IndexByte(value, 0) >= 0 {\n\t\treturn fmt.Errorf(\"invalid null character in %s %q\", field, value)\n\t}\n\treturn nil\n}\n\nfunc mqttPubTrace(pp *mqttPublish) string {","sourceCodeStart":4311,"sourceCodeEnd":4347,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/mqtt.go#L4311-L4347","documentation":"A topic (or other MQTT byte field) must be valid UTF-8; the server validates incoming topic bytes with utf8.Valid before routing or storing them. This error means the field's bytes are not decodable as UTF-8, so the server cannot safely process or log it.","triggerScenarios":"A client sends SUBSCRIBE, PUBLISH, or UNSUBSCRIBE with topic bytes that are invalid UTF-8 (e.g. raw binary data, Latin-1 encoded strings, or truncated multi-byte sequences).","commonSituations":"Publishing topics built from binary payloads or user input without encoding checks, clients using non-UTF-8 charsets (legacy systems), or byte-level slicing that splits a multi-byte UTF-8 character.","solutions":["Validate/convert the topic to UTF-8 in the client before sending (encode from the native string type to UTF-8 bytes)","Reject or sanitize user-supplied topic components that contain non-text bytes","Check for slicing bugs that cut a multi-byte rune in half and fix the boundary arithmetic","Upgrade the client library if its topic encoding is non-conformant"],"exampleFix":"// before (Go client)\ntopic := []byte(userInput)\n// after\nif !utf8.ValidString(userInput) { return errors.New(\"topic must be valid UTF-8\") }\ntopic := []byte(userInput)","handlingStrategy":"validation","validationCode":"func validTopic(b []byte) bool { return utf8.Valid(b) && bytes.IndexByte(b, 0) < 0 && len(b) > 0 }","typeGuard":"func isUTF8Bytes(b []byte) bool { return utf8.Valid(b) }","tryCatchPattern":"if err := publish(topic, payload); err != nil && strings.Contains(err.Error(), \"invalid utf8\") { sanitizeTopicAndRetry() }","preventionTips":["Never build topics from raw binary or user bytes without a UTF-8 check","Beware slicing multibyte runes; cut only at rune boundaries","Encode legacy charset data (GBK, Latin-1) to UTF-8 before use","Add a client-side utf8.Valid assertion in your publish helper"],"tags":["mqtt","utf8","encoding","topic-validation"],"backgroundTag":"utf8-validation-failed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}