dgraph-io/dgraph · critical
REUSE_RAFTID: Healthy connection to a member with same ID: %
Error message
REUSE_RAFTID: Healthy connection to a member with same ID: %+v
What it means
During Connect, Zero found an existing member with the same Raft ID as the requester but a different address, and that old member's address still has a healthy gRPC connection. Zero concludes the ID genuinely belongs to a live node elsewhere, so a new connection with the same ID is rejected to protect Raft uniqueness. (Message assembled across two Go string literals.)
Source
Thrown at dgraph/cmd/zero/zero.go:576
case member.Addr == m.Addr && m.Id == 0:
glog.Infof("Found a member with the same address. Returning: %+v", member)
conn.GetPools().Connect(m.Addr, s.tlsClientConfig)
return &pb.ConnectionState{
State: ms,
Member: member,
}, nil
case member.Addr == m.Addr && member.Id != m.Id:
// Same address. Different Id. If Id is zero, then it might be trying to connect for
// the first time. We can just directly return the membership information.
return nil, errors.Errorf("REUSE_ADDR: Duplicate address to existing member: %+v."+
" Self: +%v", member, m)
case member.Addr != m.Addr && member.Id == m.Id:
// Same Id. Different address.
if pl, err := conn.GetPools().Get(member.Addr); err == nil && pl.IsHealthy() {
// Found a healthy connection.
return nil, errors.Errorf("REUSE_RAFTID: Healthy connection to a member"+
" with same ID: %+v", member)
}
}
numberOfNodes++
}
}
// Create a connection and check validity of the address by doing an Echo.
conn.GetPools().Connect(m.Addr, s.tlsClientConfig)
createProposal := func() *pb.ZeroProposal {
s.Lock()
defer s.Unlock()
proposal := new(pb.ZeroProposal)
// Check if we already have this member.
for _, group := range s.state.Groups {
if _, has := group.Members[m.Id]; has {View on GitHub (pinned to 759e242be6)
Solutions
- Identify which instance truly owns the Raft ID and shut down or wipe the impostor's raft (p) state so it gets a fresh ID.
- If the node legitimately moved addresses, first remove the old member (RemoveNode) or let Zero expire it, then reconnect.
- Stop assigning static/duplicated --raft "id" values; let nodes auto-assign IDs with clean state.
- Check Zero /state to see the conflicting member and its address, then fix the deployment accordingly.
Example fix
// before: cloned image carries id=2 while original a1 (id=2) is still healthy // after on the clone: rm -rf p && dgraph alpha --my=a2:7080 --zero=z1:5080
Defensive patterns
Strategy: validation
Validate before calling
state := fetchZeroState("http://zero:6080/state")
for _, groups := range state.Groups {
for id, m := range groups.Members {
if id == myRaftID && m.Addr != myAddr {
return fmt.Errorf("raft id %d is live at %s; wipe local raft state or pick new id", id, m.Addr)
}
}
} Try / catch
_, err := zc.Connect(ctx, m)
if err != nil && strings.Contains(err.Error(), "REUSE_RAFTID") && strings.Contains(err.Error(), "Healthy connection") {
return fmt.Errorf("another live member already owns raft id %d; shut down the impostor: %w", m.Id, err)
} Prevention
- Verify no other live host runs the same raft id before joining (check /state).
- Avoid VM/image cloning with preserved raft state; scrub p/ in golden images.
- When moving a node to a new address, remove its old membership first.
When it happens
Trigger: Connect with m.Id equal to a current member's Id while m.Addr differs, and conn.GetPools().Get(member.Addr) succeeds and pl.IsHealthy() is true — i.e., two hosts simultaneously claiming the same Raft ID.
Common situations: Cloned VM/container images with copied raft state; a node moved to a new address without removing its old membership; a stale/recovering node reconnecting while its replacement is already healthy; misconfigured static raft IDs in fleet provisioning.
Related errors
- REUSE_RAFTID: Duplicate Raft ID %d to removed member: %+v
- Create Proposal: Invalid group: %+v
- Move all tablets from group %d before removing the last node
- NO_ADDR: No address provided: %+v
- REUSE_ADDR: Duplicate address to existing member: %+v. Self:
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/84912707617ba7d4.
Report an issue: GitHub.