nats-io/nats-server · warning
subject %q is malformed
Error message
subject %q is malformed
What it means
This internal error is produced by the monitoring/system-account service setup in events.go when a request subject received on an internal system service does not tokenize into the expected number of tokens (accReqTokens, e.g. '$SYS.REQ.ACCOUNT.<account>.<endpoint>'). The library throws it to skip a malformed system request it cannot attribute to an account.
Source
Thrown at server/events.go:1364
case "STATSZ":
h = s.noInlineCallbackStatsz(req)
default:
h = s.noInlineCallback(req)
}
subject = fmt.Sprintf(serverDirectReqSubj, s.info.ID, name)
if _, err := s.sysSubscribe(subject, h); err != nil {
s.Errorf("Error setting up internal tracking: %v", err)
return
}
subject = fmt.Sprintf(serverPingReqSubj, name)
if _, err := s.sysSubscribe(subject, h); err != nil {
s.Errorf("Error setting up internal tracking: %v", err)
return
}
}
extractAccount := func(subject string) (string, error) {
if tk := strings.Split(subject, tsep); len(tk) != accReqTokens {
return _EMPTY_, fmt.Errorf("subject %q is malformed", subject)
} else {
return tk[accReqAccIndex], nil
}
}
monAccSrvc := map[string]sysMsgHandler{
"SUBSZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
optz := &SubszEventOptions{}
s.zReq(c, reply, hdr, msg, &optz.EventFilterOptions, optz, func() (any, error) {
if acc, err := extractAccount(subject); err != nil {
return nil, err
} else {
optz.SubszOptions.Subscriptions = true
optz.SubszOptions.Account = acc
return s.Subsz(&optz.SubszOptions)
}
})
},
"CONNZ": func(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {View on GitHub (pinned to 3a66a489d2)
Solutions
- Use the canonical system request subject format, e.g. '$SYS.REQ.ACCOUNT.<account-id>.<ENDPOINT>' with all tokens present
- Prefer the server's provided request helpers/monitoring client rather than hand-building subjects
- Upgrade client monitoring tools to match the server version's system API subjects
Example fix
// before sub := "$SYS.REQ.ACCOUNT.SUBSZ" // missing account token // after sub := "$SYS.REQ.ACCOUNT." + accID + ".SUBSZ"
Defensive patterns
Strategy: type-guard
Validate before calling
func validSysReqSubject(subj string) bool {
return strings.HasPrefix(subj, "$SYS.REQ.ACCOUNT.") && len(strings.Split(subj, ".")) == 6
} Type guard
func isMalformedSubjectErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "is malformed")
} Try / catch
acc, err := extractAccount(subject)
if err != nil {
// log and drop malformed system request
return
} Prevention
- Use published system request subject constants/helpers, not hand-built strings
- Match the token count expected by your server version's system API
- Keep monitoring tools version-aligned with the server
When it happens
Trigger: A message published to a $SYS.REQ.ACCOUNT.* service subject with the wrong number of dot-separated tokens, so extractAccount's strings.Split does not yield accReqTokens tokens.
Common situations: Custom tooling publishing handcrafted $SYS request subjects; version mismatches where internal system subject schemas changed between server versions; typos in monitoring scripts.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- fetching jwt failed due to shutdown
- fetching jwt timed out
- system account not setup
- not allowed to delete system account
- error setting up pack request handling: %v
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/c70d33fc1fed426a.
Report an issue: GitHub.