{"record":{"id":"7e253f4c296f7029","repo":"nats-io/nats-server","slug":"jetstream-can-not-be-enabled-on-the-system-account","errorCode":null,"errorMessage":"jetstream can not be enabled on the system account","messagePattern":"jetstream can not be enabled on the system account","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jetstream.go","lineNumber":1202,"sourceCode":"func (a *Account) assignJetStreamLimits(limits map[string]JetStreamAccountLimits) {\n\ta.mu.Lock()\n\ta.jsLimits = limits\n\ta.mu.Unlock()\n}\n\n// EnableJetStream will enable JetStream on this account with the defined limits.\n// This is a helper for JetStreamEnableAccount.\nfunc (a *Account) EnableJetStream(limits map[string]JetStreamAccountLimits, tq chan<- func()) error {\n\ta.mu.RLock()\n\ts := a.srv\n\ta.mu.RUnlock()\n\n\tif s == nil {\n\t\treturn fmt.Errorf(\"jetstream account not registered\")\n\t}\n\n\tif s.SystemAccount() == a {\n\t\treturn fmt.Errorf(\"jetstream can not be enabled on the system account\")\n\t}\n\n\ts.mu.RLock()\n\tif s.sys == nil {\n\t\ts.mu.RUnlock()\n\t\treturn ErrServerNotRunning\n\t}\n\tsendq := s.sys.sendq\n\ts.mu.RUnlock()\n\n\t// No limits means we dynamically set up limits.\n\t// We also place limits here so we know that the account is configured for JetStream.\n\tif len(limits) == 0 {\n\t\tlimits = defaultJSAccountTiers\n\t}\n\n\ta.assignJetStreamLimits(limits)\n","sourceCodeStart":1184,"sourceCodeEnd":1220,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream.go#L1184-L1220","documentation":"JetStream cannot be enabled on the system account because the system account hosts the JetStream API services themselves; enabling user JetStream limits on it would be circular and is rejected explicitly by EnableJetStream after checking the account is registered.","triggerScenarios":"Calling EnableJetStream on the account returned by s.SystemAccount(), or on an account configured as the SystemAccount option, or on the implicit DEFAULT system account in non-operator mode.","commonSituations":"Looping over all accounts and enabling JetStream indiscriminately including the system account; copying account config from a normal account onto the system account; misreading documentation that says all accounts need JetStream enabled.","solutions":["Skip the system account when enabling JetStream: compare acc with s.SystemAccount() before calling.","Enable JetStream only on user/application accounts.","If the system account needs JetStream resources, that is handled internally by the server; no user action required.","Restructure loops to filter reserved accounts."],"exampleFix":"// before\nfor _, acc := range accounts {\n    acc.EnableJetStream(limits, tq)\n}\n// after\nsys := s.SystemAccount()\nfor _, acc := range accounts {\n    if acc == sys { continue }\n    acc.EnableJetStream(limits, tq)\n}","handlingStrategy":"validation","validationCode":"if acc == s.SystemAccount() {\n    return fmt.Errorf(\"refusing to enable JetStream on system account\")\n}","typeGuard":null,"tryCatchPattern":"if err := acc.EnableJetStream(limits, tq); err != nil {\n    if strings.Contains(err.Error(), \"system account\") {\n        log.Printf(\"skipping system account %s\", acc.Name)\n        return nil\n    }\n    return err\n}","preventionTips":["Skip s.SystemAccount() in loops enabling JetStream on all accounts","Never copy a normal account's jetstream config onto the system account","Remember the system account's JetStream usage is managed internally by the server","Name accounts distinctly (e.g. SYS) so filters are easy to apply"],"tags":["jetstream","system-account","nats-server"],"backgroundTag":"jetstream-system-account-forbidden","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}