nats-io/nats-server · error

subscribe deny: %w

Error message

subscribe deny: %w

What it means

Validation of a permission's subscribe deny list failed. The library wraps checkPermSubjectArray's error with 'subscribe deny' to indicate the DENIED subscribe subjects are invalid. Like the other permission validations, it runs during config validation of authorization blocks, users, or accounts.

Source

Thrown at server/auth.go:1746

func validatePermissionSubjects(p *Permissions) error {
	if p == nil {
		return nil
	}
	if p.Publish != nil {
		if err := checkPermSubjectArray(p.Publish.Allow, false); err != nil {
			return fmt.Errorf("publish allow: %w", err)
		}
		if err := checkPermSubjectArray(p.Publish.Deny, false); err != nil {
			return fmt.Errorf("publish deny: %w", err)
		}
	}
	if p.Subscribe != nil {
		if err := checkPermSubjectArray(p.Subscribe.Allow, true); err != nil {
			return fmt.Errorf("subscribe allow: %w", err)
		}
		if err := checkPermSubjectArray(p.Subscribe.Deny, true); err != nil {
			return fmt.Errorf("subscribe deny: %w", err)
		}
	}
	return nil
}

func validateAllowedConnectionTypes(m map[string]struct{}) error {
	for ct := range m {
		ctuc := strings.ToUpper(ct)
		switch ctuc {
		case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket,
			jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeLeafnodeWS,
			jwt.ConnectionTypeMqtt, jwt.ConnectionTypeMqttWS,
			jwt.ConnectionTypeInProcess:
		default:
			return fmt.Errorf("unknown connection type %q", ct)
		}
		if ctuc != ct {
			delete(m, ct)

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix the invalid subject in Subscribe.Deny as identified by the wrapped error.
  2. Validate wildcard placement: '>' must be last token, '*' cannot be part of a token.
  3. Remove empty or malformed entries.
  4. Run `nats-server -t -c config` to lint the configuration.

Example fix

// before
Subscribe: {Deny: []string{"foo.>>"}}
// after
Subscribe: {Deny: []string{"foo.>"}}
Defensive patterns

Strategy: validation

Validate before calling

for i, s := range perm.Subscribe.Deny {
    if s == "" || !utf8.ValidString(s) {
        return fmt.Errorf("invalid subscribe deny subject at %d: %q", i, s)
    }
}

Type guard

func validSubject(s string) bool {
    parts := strings.Split(s, ".")
    for i, t := range parts {
        if t == "" { return false }
        if strings.ContainsAny(t, "*>") && !(t == "*" || (t == ">" && i == len(parts)-1)) { return false }
    }
    return true
}

Try / catch

if err := validatePermissions(perms, true); err != nil {
    if strings.HasPrefix(err.Error(), "subscribe deny") {
        log.Fatalf("fix Subscribe.Deny subjects: %v", err)
    }
}

Prevention

When it happens

Trigger: Calling validation with a Permissions struct whose Subscribe.Deny array fails subject validation: bad wildcards, invalid characters, or empty subjects passed to checkPermSubjectArray(Subscribe.Deny, true).

Common situations: Hand-edited config deny lists (e.g. 'foo.>>' or trailing dot), generated permission sets from internal tooling, or after a config migration. Surfaces at server start or reload with the wrapped cause naming the bad subject.

Related errors


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