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
- Enable deletes in the server resolver config (configure the allowed delete type, e.g. self-delete) and reload/restart
- Remove/skip the delete request if deletes are intentionally disabled
- 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
- Enable the delete policy in server config before deploying delete tooling
- Check deleteType at startup in automation
- Keep server config and tooling expectations in sync
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
- store operation not supported for URL Resolver
- Fetch timeout %v is too smal
- account resolver missing
- failed to create mapping transform for stream import subject
- will only fetch valid account keys
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/046484001fbc48b3.
Report an issue: GitHub.