nats-io/nats-server · error
unable to add account %q to the list of dedicated routes: %v
Error message
unable to add account %q to the list of dedicated routes: %v
What it means
During cluster options reload, newly added dedicated-reserve/pool accounts (co.accsAdded) are validated with s.LookupAccount. If an added account cannot be resolved, reload fails, wrapping the lookup error, because routes require the account to exist.
Source
Thrown at server/reload.go:1704
case "nkeys":
diffOpts = append(diffOpts, &nkeysOption{})
case "cluster":
newClusterOpts := newValue.(ClusterOpts)
oldClusterOpts := oldValue.(ClusterOpts)
if err := validateClusterOpts(oldClusterOpts, newClusterOpts); err != nil {
return nil, err
}
co := &clusterOption{
newValue: newClusterOpts,
permsChanged: !reflect.DeepEqual(newClusterOpts.Permissions, oldClusterOpts.Permissions),
compressChanged: !oldClusterOpts.Compression.equals(&newClusterOpts.Compression),
}
co.diffPoolAndAccounts(&oldClusterOpts)
// If there are added accounts, first make sure that we can look them up.
// If we can't let's fail the reload.
for _, acc := range co.accsAdded {
if _, err := s.LookupAccount(acc); err != nil {
return nil, fmt.Errorf("unable to add account %q to the list of dedicated routes: %v", acc, err)
}
}
// If pool_size has been set to negative (but was not before), then let's
// add the system account to the list of removed accounts (we don't have
// to check if already there, duplicates are ok in that case).
if newClusterOpts.PoolSize < 0 && oldClusterOpts.PoolSize >= 0 {
if sys := s.SystemAccount(); sys != nil {
co.accsRemoved = append(co.accsRemoved, sys.GetName())
}
}
diffOpts = append(diffOpts, co)
case "routes":
add, remove := diffRoutes(oldValue.([]*url.URL), newValue.([]*url.URL))
diffOpts = append(diffOpts, &routesOption{add: add, remove: remove})
case "maxconn":
diffOpts = append(diffOpts, &maxConnOption{newValue: newValue.(int)})
case "pidfile":
diffOpts = append(diffOpts, &pidFileOption{newValue: newValue.(string)})View on GitHub (pinned to 3a66a489d2)
Solutions
- Define the referenced accounts in the accounts{} block (or resolver) so LookupAccount succeeds, then reload again.
- Fix the account name typo in the cluster dedicated accounts list.
- Check resolver setup (memory resolver payload / URL resolver) includes the new accounts and the resolver is reachable.
- Revert the pool/account change if the accounts cannot be provisioned yet.
Example fix
// before
cluster { pool_size: 2 } // account "missing_acc" not defined
// after
accounts { missing_acc { users: [...] } }
cluster { pool_size: 2 } Defensive patterns
Strategy: validation
Validate before calling
for _, accName := range newClusterDedicatedAccounts {
if _, err := srv.LookupAccount(accName); err != nil {
return fmt.Errorf("account %q must be defined before reload", accName)
}
} Try / catch
if err := srv.Reload(); err != nil {
if strings.Contains(err.Error(), "dedicated routes") {
log.Printf("add missing accounts and reload again: %v", err)
}
} Prevention
- Define all cluster pool/dedicated accounts in accounts{} or the resolver before reload.
- Validate account names with the resolver before issuing SIGHUP.
- Avoid negative pool_size changes referencing undefined accounts.
When it happens
Trigger: cluster.pool_size / dedicated cluster accounts changed so that new accounts are added, but LookupAccount(name) fails — the account is not defined or not yet resolvable (no resolver hit, or listed only in the new config's removed/added sets inconsistently).
Common situations: Setting cluster { pool_size: -N } with accounts not defined in `accounts{}`; misspelled account names in cluster resolvers; memory resolver config missing the referenced account.
Related errors
- remote leafnode has same cluster name
- duplicate server name
- JS_CONSUMER_OFFLINE
- shutting down
- system limit reached
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/f8400846c250eb6b.
Report an issue: GitHub.