nats-io/nats-server · error

raft: leader should be exactly %d bytes

Error message

raft: leader should be exactly %d bytes

What it means

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.

Source

Thrown at server/raft.go:376

	errCorruptPeers      = errors.New("raft: corrupt peer state")
	errEntryLoadFailed   = errors.New("raft: could not load entry from WAL")
	errEntryStoreFailed  = errors.New("raft: could not store entry to WAL")
	errNodeClosed        = errors.New("raft: node is closed")
	errNodeRemoved       = errors.New("raft: peer was removed")
	errBadSnapName       = errors.New("raft: snapshot name could not be parsed")
	errNoSnapAvailable   = errors.New("raft: no snapshot available")
	errSnapInProgress    = errors.New("raft: snapshot is already in progress")
	errSnapAborted       = errors.New("raft: snapshot was aborted")
	errCatchupsRunning   = errors.New("raft: snapshot can not be installed while catchups running")
	errRescueBadQuorum   = errors.New("raft: rescue quorum must be between 1 and current quorum")
	errRescueLeaderKnown = errors.New("raft: leader is known")
	errRescueNotVoting   = errors.New("raft: not a voting member")
	errRescueEmptyLog    = errors.New("raft: log is empty")
	errSnapshotCorrupt   = errors.New("raft: snapshot corrupt")
	errTooManyPrefs      = errors.New("raft: stepdown requires at most one preferred new leader")
	errNoPeerState       = errors.New("raft: no peerstate")
	errAdjustBootCluster = errors.New("raft: can not adjust boot peer size on established group")
	errLeaderLen         = fmt.Errorf("raft: leader should be exactly %d bytes", idLen)
	errTooManyEntries    = errors.New("raft: append entry can contain a max of 64k entries")
	errBadAppendEntry    = errors.New("raft: append entry corrupt")
	errNoInternalClient  = errors.New("raft: no internal client")
	errMembershipChange  = errors.New("raft: membership change in progress")
	errRemoveLastNode    = errors.New("raft: cannot remove the last peer")
	errPeerNotFound      = errors.New("raft: peer not found")
	errNotManaged        = errors.New("raft: group membership is not managed")
	errNotLeaderless     = errors.New("raft: group is not leaderless")
	errQuorumPossible    = errors.New("raft: remaining peers could still reach quorum")
)

// This will bootstrap a raftNode by writing its config into the store directory.
func (s *Server) bootstrapRaftNode(cfg *RaftConfig, knownPeers []string, allPeersKnown bool) error {
	if cfg == nil {
		return errNilCfg
	}
	// Check validity of peers if presented.
	for _, p := range knownPeers {

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Set ae.leader to a valid idLen-byte node ID, or leave it empty ("", meaning noLeader).
  2. Populate the leader from a real raft node ID (as generated by the server) rather than a placeholder.
  3. If decoding external data, validate the leader length before assignment.

Example fix

// before
ae.leader = "foo_bar_baz"
// after
ae.leader = "" // or a valid idLen-byte node ID
Defensive patterns

Strategy: validation

Validate before calling

// Validate leader length before encoding
if ll := len(ae.leader); ll != idLen && ll != 0 {
    return fmt.Errorf("leader must be %d bytes or empty, got %d", idLen, ll)
}

Type guard

func isValidLeader(id string) bool {
    return len(id) == idLen || len(id) == 0
}

Try / catch

if _, err := ae.encode(nil); err != nil {
    return fmt.Errorf("fix ae.leader (%q) to an idLen-byte node ID or empty: %w", ae.leader, err)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/8d327d7976c7a324. Report an issue: GitHub.