nats-io/nats-server · error
cluster import allow: %w
Error message
cluster import allow: %w
What it means
checkClusterPermissionSubjects() validates the Permissions block for cluster-scoped account imports/exports. When perms.Publish.Allow contains a subject that fails checkPermSubjectArray validation, the error is wrapped as 'cluster import allow: %w'. Note the wording is legacy/confusing: it reports the publish (subscribe-side) permissions even though it says 'import'.
Source
Thrown at server/opts.go:3399
func setClusterPermissions(opts *ClusterOpts, perms *Permissions) {
// Import is whether or not we will send a SUB for interest to the other side.
// Export is whether or not we will accept a SUB from the remote for a given subject.
// Both only effect interest registration.
// The parsing sets Import into Publish and Export into Subscribe, convert
// accordingly.
opts.Permissions = &RoutePermissions{
Import: perms.Publish,
Export: perms.Subscribe,
}
}
func checkClusterPermissionSubjects(perms *Permissions) error {
if perms == nil {
return nil
}
if perms.Publish != nil {
if err := checkPermSubjectArray(perms.Publish.Allow, false); err != nil {
return fmt.Errorf("cluster import allow: %w", err)
}
if err := checkPermSubjectArray(perms.Publish.Deny, false); err != nil {
return fmt.Errorf("cluster import deny: %w", err)
}
}
if perms.Subscribe != nil {
if err := checkPermSubjectArray(perms.Subscribe.Allow, false); err != nil {
return fmt.Errorf("cluster export allow: %w", err)
}
if err := checkPermSubjectArray(perms.Subscribe.Deny, false); err != nil {
return fmt.Errorf("cluster export deny: %w", err)
}
}
return nil
}
// Temp structures to hold account import and export defintions since they need
// to be processed after being parsed.View on GitHub (pinned to 3a66a489d2)
Solutions
- Fix the offending subject in Permissions.Publish.Allow to a valid NATS subject (see wrapped inner error naming the subject)
- Remove invalid wildcard usage (e.g. 'foo.>' is fine, 'foo.>.bar' is not)
- Remove empty or whitespace subjects from the array
- Run the config through nats-server's config validation before deployment
Example fix
// before
publish: { allow: ["foo.>.bar"] }
// after
publish: { allow: ["foo.>"] } Defensive patterns
Strategy: validation
Validate before calling
for _, s := range perms.Publish.Allow {
if !server.IsValidSubject(s) {
return fmt.Errorf("invalid publish allow subject %q", s)
}
} Type guard
func validSubjects(sa []string) bool {
for _, s := range sa {
if !IsValidSubject(s) { return false }
}
return true
} Try / catch
if err := opts.ProcessConfigFile(path); err != nil {
log.Fatalf("config error: %v", err)
} Prevention
- Validate all permission subjects at config-generation time
- Quote YAML subject strings to avoid whitespace injection
- Keep wildcards per NATS rules: '*' single token, '>' last token only
When it happens
Trigger: Configuring an account's Permissions.Publish.Allow array (in clustered/config-file contexts) with a subject that is not a valid NATS subject, e.g. containing ' ' or invalid wildcards.
Common situations: Typo in a publish permission subject such as a trailing dot, space, or invalid '>' placement; queue-qualified subjects used where they are not allowed (allowQueue=false here); machine-generated config inserting empty strings.
Related errors
- cluster import deny: %w
- cluster export allow: %w
- cluster export deny: %w
- subject %q is not a valid subject
- publish deny: %w
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/003147940eabed0e.
Report an issue: GitHub.