{"record":{"id":"f04a1978c80e1a8a","repo":"nats-io/nats-server","slug":"raft-illegal-peer-q","errorCode":null,"errorMessage":"raft: illegal peer: %q","messagePattern":"raft: illegal peer: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/raft.go","lineNumber":396,"sourceCode":"\terrBadAppendEntry    = errors.New(\"raft: append entry corrupt\")\n\terrNoInternalClient  = errors.New(\"raft: no internal client\")\n\terrMembershipChange  = errors.New(\"raft: membership change in progress\")\n\terrRemoveLastNode    = errors.New(\"raft: cannot remove the last peer\")\n\terrPeerNotFound      = errors.New(\"raft: peer not found\")\n\terrNotManaged        = errors.New(\"raft: group membership is not managed\")\n\terrNotLeaderless     = errors.New(\"raft: group is not leaderless\")\n\terrQuorumPossible    = errors.New(\"raft: remaining peers could still reach quorum\")\n)\n\n// This will bootstrap a raftNode by writing its config into the store directory.\nfunc (s *Server) bootstrapRaftNode(cfg *RaftConfig, knownPeers []string, allPeersKnown bool) error {\n\tif cfg == nil {\n\t\treturn errNilCfg\n\t}\n\t// Check validity of peers if presented.\n\tfor _, p := range knownPeers {\n\t\tif len(p) != idLen {\n\t\t\treturn fmt.Errorf(\"raft: illegal peer: %q\", p)\n\t\t}\n\t}\n\texpected := len(knownPeers)\n\t// We need to adjust this is all peers are not known.\n\tif !allPeersKnown {\n\t\ts.Debugf(\"Determining expected peer size for JetStream meta group\")\n\t\tif expected < 2 {\n\t\t\texpected = 2\n\t\t}\n\t\topts := s.getOpts()\n\t\tnrs := len(opts.Routes)\n\n\t\tcn := s.ClusterName()\n\t\tngwps := 0\n\t\tfor _, gw := range opts.Gateway.Gateways {\n\t\t\t// Ignore our own cluster if specified.\n\t\t\tif gw.Name == cn {\n\t\t\t\tcontinue","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/raft.go#L378-L414","documentation":"When creating a raft group, NATS validates each peer in the knownPeers list has exactly idLen bytes. A peer ID of any other length means it is not a valid node ID, and the group creation fails with this quoted peer name in the error.","triggerScenarios":"Calling the raft group creation path (stream/meta assignment) with a knownPeers slice containing a malformed/short/long peer ID.","commonSituations":"Passing human-readable or placeholder names instead of real raft node IDs, corrupted peer state restored from disk, or custom tooling building the peer list manually.","solutions":["Ensure every entry in knownPeers is a genuine server-generated node ID of idLen bytes.","Remove or fix the offending peer reported in %q in the error message.","Re-derive the peer list from the actual cluster membership instead of a hand-written list.","Validate peer IDs (length check) before constructing the raft config."],"exampleFix":"// before\nknownPeers := []string{\"node-a\", \"node-b\"}\n// after\nknownPeers := clusterMembers() // real idLen-byte node IDs","handlingStrategy":"validation","validationCode":"// Validate all peer IDs before building the raft config\nfor _, p := range knownPeers {\n    if len(p) != idLen {\n        return fmt.Errorf(\"peer %q is not %d bytes\", p, idLen)\n    }\n}","typeGuard":"func isValidPeerID(p string) bool {\n    return len(p) == idLen\n}","tryCatchPattern":"if _, err := createGroup(cfg, knownPeers, ...); err != nil {\n    return fmt.Errorf(\"rebuild peer list from cluster membership: %w\", err)\n}","preventionTips":["Derive knownPeers from actual cluster membership APIs.","Never insert friendly names into raft peer lists.","Sanitize peer state restored from snapshots/disk."],"tags":["raft","jetstream","cluster"],"backgroundTag":"raft-invalid-peer-id","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}