nats-io/nats-server · error

cluster export allow: %w

Error message

cluster export allow: %w

What it means

checkClusterPermissionSubjects() wraps failures from checkPermSubjectArray(perms.Subscribe.Allow, false) with 'cluster export allow: %w'. Despite the 'export' wording, it validates the Subscribe.Allow array of the permissions block; a subject there is not a valid NATS subject.

Source

Thrown at server/opts.go:3407

		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.
type export struct {
	acc  *Account
	sub  string
	accs []string
	rt   ServiceRespType
	lat  *serviceLatency
	rthr time.Duration
	tPos uint

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Correct the subject identified by the wrapped inner error in Permissions.Subscribe.Allow
  2. Remove duplicate/empty tokens ('foo..bar' -> 'foo.bar')
  3. Move queue-qualified subjects ("subj queue") to contexts that allow them, or drop the queue part
  4. Lint the NATS config file before restart

Example fix

// before
subscribe: { allow: ["foo..bar"] }
// after
subscribe: { allow: ["foo.bar"] }
Defensive patterns

Strategy: validation

Validate before calling

for _, s := range perms.Subscribe.Allow {
	if !server.IsValidSubject(s) {
		return fmt.Errorf("invalid subscribe 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

When it happens

Trigger: Permissions.Subscribe.Allow contains a malformed subject (bad wildcard, empty entry, whitespace) during option/config validation.

Common situations: Misconfigured subscribe permissions in account/user config; accidentally including queue-group syntax in a non-queue context; typos like 'foo..bar'.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/49cc01662ef97fab. Report an issue: GitHub.