nats-io/nats-server · error

publish deny: %w

Error message

publish deny: %w

What it means

Validation of a permission's publish deny list failed. This library wraps the underlying subject-array validation error with the 'publish deny' prefix to indicate that the DENY subjects of the Publish permission block are malformed (e.g. invalid wildcard usage or empty subject). It is thrown while validating authorization blocks, users/nkeys permissions, or account-scoped permission structures at server startup or config reload.

Source

Thrown at server/auth.go:1738

			return err
		}
		if err := validatePermissionSubjects(u.Permissions); err != nil {
			return fmt.Errorf("invalid permissions for nkey %q: %w", u.Nkey, err)
		}
	}
	return validateNoAuthUser(o, o.NoAuthUser)
}

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,

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix the offending subject in the Publish.Deny list — the wrapped error names the exact invalid subject.
  2. Run nats-server --signal reload or start with -V/trace logging to see the wrapped subject detail.
  3. Remove empty strings and duplicate entries from the deny array.
  4. Validate subject syntax rules: tokens separated by '.', wildcards '*' (one token) and '>' (tail only).

Example fix

// before
perms := server.Permissions{Publish: {Deny: []string{"foo.**", ""}}}
// after
perms := server.Permissions{Publish: {Deny: []string{"foo.bar", "foo.>"}}}
Defensive patterns

Strategy: validation

Validate before calling

for i, s := range perm.Publish.Deny {
    if s == "" || strings.Contains(s, " ") {
        return fmt.Errorf("invalid publish deny subject at %d: %q", i, s)
    }
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling validatePermissions (or config validation) with a Permissions struct whose Publish.Deny array contains invalid subjects — e.g. wildcards in illegal positions, tokens exceeding token limits, or subjects with invalid characters. Any []string passed to checkPermSubjectArray(Publish.Deny, false) that fails validation.

Common situations: Typos in nats_server.conf authorization block deny: lists, programmatically built Permissions withSubjects like 'foo.>' nested inside another wildcard, or empty-string entries in the deny array. Often surfaces during server startup after editing the authorization section or when generating users via code/tools.

Related errors


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