nats-io/nats-server · error

delete must be enabled in server config

Error message

delete must be enabled in server config

What it means

In the built-in account JWT resolver delete flow, a delete request received over the internal delete subject is validated against the store's delete policy. When store.deleteType is NoDelete (deletes not enabled in server config), the request is rejected with this error before any signature checks.

Source

Thrown at server/accounts.go:4369

		s.Debugf("list request responded with %d account ids", len(accIds))
		server := &ServerInfo{}
		response := map[string]any{"server": server, "data": accIds}
		s.sendInternalMsgLocked(reply, _EMPTY_, server, response)
	}
}

func handleDeleteRequest(store *DirJWTStore, s *Server, msg []byte, reply string) {
	var accIds []any
	var subj, sysAccName string
	if sysAcc := s.SystemAccount(); sysAcc != nil {
		sysAccName = sysAcc.GetName()
	}
	// Only operator and operator signing key are allowed to delete
	gk, err := jwt.DecodeGeneric(string(msg))
	if err == nil {
		subj = gk.Subject
		if store.deleteType == NoDelete {
			err = fmt.Errorf("delete must be enabled in server config")
		} else if subj != gk.Issuer {
			err = fmt.Errorf("not self signed")
		} else if _, ok := store.operator[gk.Issuer]; !ok {
			err = fmt.Errorf("not trusted")
		} else if list, ok := gk.Data["accounts"]; !ok {
			err = fmt.Errorf("malformed request")
		} else if accIds, ok = list.([]any); !ok {
			err = fmt.Errorf("malformed request")
		} else {
			for _, entry := range accIds {
				if acc, ok := entry.(string); !ok ||
					acc == _EMPTY_ || !nkeys.IsValidPublicAccountKey(acc) {
					err = fmt.Errorf("malformed request")
					break
				} else if acc == sysAccName {
					err = fmt.Errorf("not allowed to delete system account")
					break
				}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Enable deletes in the server resolver config (configure the allowed delete type, e.g. self-delete) and reload/restart
  2. Remove/skip the delete request if deletes are intentionally disabled
  3. Verify the store's deleteType before issuing delete requests from tooling

Example fix

// before
// server.conf
resolver: MEMORY
// after
// server.conf
resolver: MEMORY
delete: Self (enable deletes per desired policy)
Defensive patterns

Strategy: validation

Validate before calling

// client-side: only issue delete requests when server config enables deletes
if resolverDeleteType == NoDelete {
    return errors.New("refusing to send delete: deletes disabled in server config")
}

Try / catch

if err := sendDeleteRequest(store, msg); err != nil {
    if strings.Contains(err.Error(), "delete must be enabled") {
        // notify operator to enable deletes or drop the request
    }
}

Prevention

When it happens

Trigger: Publishing a delete request JWT to the account resolver delete subject while the server is configured without deletes (delete not enabled), regardless of who signed it.

Common situations: Operator tooling issuing account deletes against a server whose resolver config lacks delete enablement; forgetting to add the delete config option when deploying delete-capable tooling.

Related errors


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