{"record":{"id":"da5868263f4def93","repo":"nats-io/nats-server","slug":"10005","errorCode":"10005","errorMessage":"preferred server %q is already leader","messagePattern":"preferred server %q is already leader","errorType":"error_code","errorClass":"JSClusterNoPeersError","httpStatus":400,"severity":"error","filePath":"server/jetstream_api.go","lineNumber":3365,"sourceCode":"// should check for return API errors and return those to the requestor if needed.\nfunc (s *Server) getStepDownPreferredPlacement(group RaftNode, placement *Placement) (string, *ApiError) {\n\tif placement == nil {\n\t\treturn _EMPTY_, nil\n\t}\n\tvar preferredLeader string\n\tif placement.Preferred != _EMPTY_ {\n\t\tfor _, p := range group.Peers() {\n\t\t\tsi, ok := s.nodeToInfo.Load(p.ID)\n\t\t\tif !ok || si == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif si.(nodeInfo).name == placement.Preferred {\n\t\t\t\tpreferredLeader = p.ID\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif preferredLeader == group.ID() {\n\t\t\treturn _EMPTY_, NewJSClusterNoPeersError(fmt.Errorf(\"preferred server %q is already leader\", placement.Preferred))\n\t\t}\n\t\tif preferredLeader == _EMPTY_ {\n\t\t\treturn _EMPTY_, NewJSClusterNoPeersError(fmt.Errorf(\"preferred server %q not known\", placement.Preferred))\n\t\t}\n\t} else {\n\t\tpossiblePeers := make(map[*Peer]nodeInfo, len(group.Peers()))\n\t\tourID := group.ID()\n\t\tfor _, p := range group.Peers() {\n\t\t\tif p == nil {\n\t\t\t\tcontinue // ... shouldn't happen.\n\t\t\t}\n\t\t\tsi, ok := s.nodeToInfo.Load(p.ID)\n\t\t\tif !ok || si == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tni := si.(nodeInfo)\n\t\t\tif ni.offline || p.ID == ourID {\n\t\t\t\tcontinue","sourceCodeStart":3347,"sourceCodeEnd":3383,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream_api.go#L3347-L3383","documentation":"JetStream cluster placement error (JSClusterNoPeersError, code 10005). When a stream/mirror/copy placement specifies a Preferred server, the server checks whether that peer is already the RAFT group leader. If the preferred server is already leader, it cannot be re-elected as a new leader via this operation, so the request fails.","triggerScenarios":"Issuing a leader-stepdown or stream re-placement API request (e.g. jsm stream leader stepdown --preferred-server=X, or the JS API leader stepdown endpoint) where server X is already the current leader of the group.","commonSituations":"Automation/scheduler scripts that run stepdown with a preferred target without first checking the current leader; re-running a failed maintenance job after the preferred server already became leader.","solutions":["Check the current leader first; skip the stepdown if the preferred server already leads","Issue the stepdown without the Preferred field to let the cluster choose a new leader","Make automation idempotent: treat this error as success (desired state already achieved)"],"exampleFix":"// before\njsm stream leader stepdown STREAM --preferred-server=nats-3\n// after\nLEADER=$(jsm stream info STREAM -j | jq -r .cluster.leader)\n[ \"$LEADER\" = \"nats-3\" ] || jsm stream leader stepdown STREAM --preferred-server=nats-3","handlingStrategy":"validation","validationCode":"leader := getStreamLeader(streamName)\nif leader == preferredServer {\n\treturn // already desired state, skip stepdown\n}","typeGuard":"func stepdownNeeded(currentLeader, preferred string) bool { return currentLeader != preferred }","tryCatchPattern":"err := stepdown(stream, preferred)\nvar apiErr *jsm.APIError\nif errors.As(err, &apiErr) && strings.Contains(apiErr.Description, \"is already leader\") {\n\t// treat as success: preferred server already leads\n}","preventionTips":["Read the stream's cluster.leader before issuing stepdown","Make maintenance automation idempotent against this error"],"tags":["jetstream","clustering","raft","placement","nats-server"],"backgroundTag":"preferred-server-already-leader","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}