{"record":{"id":"8d327d7976c7a324","repo":"nats-io/nats-server","slug":"raft-leader-should-be-exactly-d-bytes","errorCode":null,"errorMessage":"raft: leader should be exactly %d bytes","messagePattern":"raft: leader should be exactly (.+?) bytes","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/raft.go","lineNumber":376,"sourceCode":"\terrCorruptPeers      = errors.New(\"raft: corrupt peer state\")\n\terrEntryLoadFailed   = errors.New(\"raft: could not load entry from WAL\")\n\terrEntryStoreFailed  = errors.New(\"raft: could not store entry to WAL\")\n\terrNodeClosed        = errors.New(\"raft: node is closed\")\n\terrNodeRemoved       = errors.New(\"raft: peer was removed\")\n\terrBadSnapName       = errors.New(\"raft: snapshot name could not be parsed\")\n\terrNoSnapAvailable   = errors.New(\"raft: no snapshot available\")\n\terrSnapInProgress    = errors.New(\"raft: snapshot is already in progress\")\n\terrSnapAborted       = errors.New(\"raft: snapshot was aborted\")\n\terrCatchupsRunning   = errors.New(\"raft: snapshot can not be installed while catchups running\")\n\terrRescueBadQuorum   = errors.New(\"raft: rescue quorum must be between 1 and current quorum\")\n\terrRescueLeaderKnown = errors.New(\"raft: leader is known\")\n\terrRescueNotVoting   = errors.New(\"raft: not a voting member\")\n\terrRescueEmptyLog    = errors.New(\"raft: log is empty\")\n\terrSnapshotCorrupt   = errors.New(\"raft: snapshot corrupt\")\n\terrTooManyPrefs      = errors.New(\"raft: stepdown requires at most one preferred new leader\")\n\terrNoPeerState       = errors.New(\"raft: no peerstate\")\n\terrAdjustBootCluster = errors.New(\"raft: can not adjust boot peer size on established group\")\n\terrLeaderLen         = fmt.Errorf(\"raft: leader should be exactly %d bytes\", idLen)\n\terrTooManyEntries    = errors.New(\"raft: append entry can contain a max of 64k entries\")\n\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 {","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/raft.go#L358-L394","documentation":"errLeaderLen is a package-level error in the NATS raft implementation stating that a raft leader ID must be exactly idLen bytes (or empty). appendEntry.encode validates the leader length before serializing and fails with this error for any other length.","triggerScenarios":"Calling appendEntry.encode with a leader string whose length is neither idLen nor 0 (e.g. the test sets leader to \"foo_bar_baz\", 11 bytes).","commonSituations":"Hand-constructing appendEntry in tests or tooling with an arbitrary leader string, or corrupted in-memory raft state where the leader ID was truncated/extended.","solutions":["Set ae.leader to a valid idLen-byte node ID, or leave it empty (\"\", meaning noLeader).","Populate the leader from a real raft node ID (as generated by the server) rather than a placeholder.","If decoding external data, validate the leader length before assignment."],"exampleFix":"// before\nae.leader = \"foo_bar_baz\"\n// after\nae.leader = \"\" // or a valid idLen-byte node ID","handlingStrategy":"validation","validationCode":"// Validate leader length before encoding\nif ll := len(ae.leader); ll != idLen && ll != 0 {\n    return fmt.Errorf(\"leader must be %d bytes or empty, got %d\", idLen, ll)\n}","typeGuard":"func isValidLeader(id string) bool {\n    return len(id) == idLen || len(id) == 0\n}","tryCatchPattern":"if _, err := ae.encode(nil); err != nil {\n    return fmt.Errorf(\"fix ae.leader (%q) to an idLen-byte node ID or empty: %w\", ae.leader, err)\n}","preventionTips":["Never hardcode placeholder leader strings in tests/tooling.","Copy leader IDs from real raft state, not human-readable names.","Keep the empty string convention for noLeader."],"tags":["raft","encoding","jetstream"],"backgroundTag":"raft-invalid-node-id-length","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}