nats-io/nats-server · error
invalid test subject, must be valid publish subject: %s
Error message
invalid test subject, must be valid publish subject: %s
What it means
Subsz rejects the Test option when the provided subject is not a valid publish (literal, no wildcard) subject. The test filter matches connections whose subscriptions would receive a message published to this subject, so only concrete literal subjects are accepted.
Source
Thrown at server/monitor.go:1033
filterAcc string
limit = DefaultSubListSize
)
if opts != nil {
subdetail = opts.Subscriptions
offset = opts.Offset
if offset < 0 {
offset = 0
}
limit = opts.Limit
if limit <= 0 {
limit = DefaultSubListSize
}
if opts.Test != _EMPTY_ {
testSub = opts.Test
test = true
if !IsValidLiteralSubject(testSub) {
return nil, fmt.Errorf("invalid test subject, must be valid publish subject: %s", testSub)
}
}
if opts.Account != _EMPTY_ {
filterAcc = opts.Account
}
}
slStats := &SublistStats{}
// FIXME(dlc) - Make account aware.
sz := &Subsz{
ID: s.info.ID,
Now: time.Now().UTC(),
SublistStats: slStats,
Total: 0,
Offset: offset,
Limit: limit,
Subs: nil,View on GitHub (pinned to 3a66a489d2)
Solutions
- Pass a fully concrete subject with no * or > tokens: test=foo.bar.baz
- Pre-validate with server.IsValidLiteralSubject(subject) before calling Subsz
- If users need wildcard matching of subscriptions, present the returned subscription list and filter client-side instead
Example fix
// before
subs, err := s.Subsz(&server.ConnzOptions{Test: "foo.*.bar"})
// after
subs, err := s.Subsz(&server.ConnzOptions{Test: "foo.baz.bar"}) Defensive patterns
Strategy: validation
Validate before calling
if !server.IsValidLiteralSubject(testSubject) {
return fmt.Errorf("test subject must be a concrete publish subject, got %q", testSubject)
} Try / catch
subs, err := srv.Subsz(opts)
if err != nil && strings.Contains(err.Error(), "invalid test subject") {
return nil, fmt.Errorf("%q is not a literal subject; wildcards are not allowed for Test", opts.Test)
} Prevention
- Strip or reject * and > tokens before passing a user subject to Test
- Use server.IsValidLiteralSubject as the single source of truth
- Offer wildcard matching client-side on the returned subscription list instead
When it happens
Trigger: Calling Subsz with ConnzOptions.Test set to a subject containing wildcards (foo.*.bar, foo.>) or otherwise failing IsValidLiteralSubject; requesting /subsz?test=foo.*.
Common situations: Building subscription inspection tools where users type wildcard patterns into the test field; reusing subscription subjects (which may contain wildcards) as test subjects.
Related errors
- fetching jwt failed due to shutdown
- fetching jwt timed out
- subject %q is malformed
- default_js_domain contains account %q with invalid domain na
- invalid domain name: derived %q is not a valid subject
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/899d79553553ab88.
Report an issue: GitHub.