nats-io/nats-server · error
subject %q is not a valid subject
Error message
subject %q is not a valid subject
What it means
checkPermSubjectArray() iterates permission subject arrays and requires each entry to pass IsValidSubject. When the array is not queue-qualified (allowQueue=false), the first invalid subject aborts with 'subject %q is not a valid subject', naming the offending entry.
Source
Thrown at server/opts.go:5056
continue
}
p.Deny = subjects
default:
if !tk.IsUsedVariable() {
err := &configErr{tk, fmt.Sprintf("Unknown field name %q parsing subject permissions, only 'allow' or 'deny' are permitted", k)}
*errors = append(*errors, err)
}
}
}
return p, nil
}
// Helper function to validate permissions subjects.
func checkPermSubjectArray(sa []string, allowQueue bool) error {
for _, s := range sa {
if !IsValidSubject(s) {
if !allowQueue {
return fmt.Errorf("subject %q is not a valid subject", s)
}
// Check here if this is a queue group qualified subject.
elements := strings.Fields(s)
if len(elements) != 2 {
return fmt.Errorf("subject %q is not a valid subject", s)
} else if !IsValidSubject(elements[0]) {
return fmt.Errorf("subject %q is not a valid subject", elements[0])
} else if !IsValidSubject(elements[1]) {
return fmt.Errorf("queue %q is not a valid queue", elements[1])
}
}
}
return nil
}
// PrintTLSHelpAndDie prints TLS usage and exits.
func PrintTLSHelpAndDie() {
fmt.Printf("%s", tlsUsage)View on GitHub (pinned to 3a66a489d2)
Solutions
- Correct the subject printed in the error to a valid NATS subject (tokens of alphanumerics/underscore, '*' per token, '>' only last)
- Quote subjects in YAML so spaces are not injected
- Remove empty entries from the array
- Use a queue-permission context (with queue names) only where queue subjects are permitted
Example fix
// before allow: ["foo bar"] // after allow: ["foo.bar"]
Defensive patterns
Strategy: validation
Validate before calling
for _, s := range subjects {
if !server.IsValidSubject(s) {
return fmt.Errorf("bad permission subject %q", s)
}
} Type guard
func isPermSubject(s string) bool { return IsValidSubject(s) } Try / catch
if err := server.ProcessConfigFile(path); err != nil {
var subjErr *SubjectErr // or string match on 'not a valid subject'
if strings.Contains(err.Error(), "not a valid subject") {
log.Fatalf("fix subject in config: %v", err)
}
} Prevention
- Quote all subject strings in YAML to prevent token splitting
- Validate subjects when generating config
- Only use '*' per token and '>' as final token
When it happens
Trigger: Any permissions allow/deny array (publish/subscribe) containing a subject that fails NATS subject rules — e.g. 'foo bar' in a non-queue array, empty string, token with illegal characters like '-' or '@', or misplaced wildcards.
Common situations: Copy-pasted subjects with trailing spaces; queue-group syntax ("subj queue") pasted into a plain permissions array; using characters outside the allowed set; YAML folding turning a subject into multiple tokens.
Related errors
- cluster import allow: %w
- cluster import deny: %w
- cluster export allow: %w
- cluster export deny: %w
- publish deny: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/7b785ce1b4c226e2.
Report an issue: GitHub.