dapr/dapr · critical

address for node %s not found in raft peers %s

Error message

address for node %s not found in raft peers %s

What it means

AddressForID (pkg/placement/peers/peers.go:28) scans the PeerInfo list parsed from --initial-cluster for the ID passed as --id (default dapr-placement-0); it is called from leadership.New at startup. If --id matches no entry key, the server cannot learn its own raft bind address and construction fails with this error. It also fires when the initial-cluster entries were parsed from malformed values that shifted the id=address pairing.

Source

Thrown at pkg/placement/peers/peers.go:35

	"fmt"

	"github.com/hashicorp/raft"
)

// PeerInfo represents raft peer node information.
type PeerInfo struct {
	ID      string
	Address string
}

func AddressForID(id string, nodes []PeerInfo) (string, error) {
	for _, node := range nodes {
		if node.ID == id {
			return node.Address, nil
		}
	}

	return "", fmt.Errorf("address for node %s not found in raft peers %s", id, nodes)
}

func BootstrapConfig(peers []PeerInfo) (*raft.Configuration, error) {
	raftConfig := &raft.Configuration{
		Servers: make([]raft.Server, len(peers)),
	}

	for i, p := range peers {
		raftConfig.Servers[i] = raft.Server{
			ID:      raft.ServerID(p.ID),
			Address: raft.ServerAddress(p.Address),
		}
	}

	return raftConfig, nil
}

View on GitHub (pinned to 74ad417027)

Solutions

  1. Set --id to exactly one key present in --initial-cluster (keys are the id= prefixes).
  2. Regenerate --initial-cluster covering every replica with consistent keys (the chart derives both from the statefulset).
  3. Print/validate the parsed peers before start: each entry must be id=host:port with unique ids.

Example fix

# before
--id=p1 --initial-cluster=dapr-placement-0=127.0.0.1:8201   # p1 not a peer key
# after
--id=dapr-placement-0 --initial-cluster=dapr-placement-0=127.0.0.1:8201
Defensive patterns

Strategy: validation

Validate before calling

// Validate flags before leadership.New (where AddressForID is called).
func validatePlacementFlags(id string, peers []peers.PeerInfo) error {
	if id == "" {
		return errors.New("--id is required")
	}
	if len(peers) == 0 {
		return errors.New("--initial-cluster parsed to zero peers")
	}
	for _, p := range peers {
		if p.ID == id {
			return nil
		}
	}
	return fmt.Errorf("--id %q not found in --initial-cluster keys %v", id, peerIDs(peers))
}

Type guard

func hasPeer(id string, peers []peers.PeerInfo) bool {
	for _, p := range peers {
		if p.ID == id {
			return true
		}
	}
	return false
}

Try / catch

leadershipSvc, err := leadership.New(leadership.Options{ID: id, Peers: peers, /* ... */})
if err != nil {
	// startup config error: fix --id / --initial-cluster key mismatch; do not retry
	log.Fatalf("placement identity not in raft peers: %v", err)
}

Prevention

When it happens

Trigger: --id=p1 while --initial-cluster keys are dapr-placement-0=...; --initial-cluster empty or malformed so the parsed peer list is empty; statefulset renamed but flags not updated; helm overrides changing replica count without regenerating initial-cluster.

Common situations: Hand-rolled multi-node placement deployments where id names drift from peer keys; local test harnesses assembling flags manually.

Related errors


AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16). Data as JSON: /api/errors/e835a57617ccda7f. Report an issue: GitHub.