dgraph-io/dgraph · error

Unknown group for member: %+v

Error message

Unknown group for member: %+v

What it means

createProposals checks that each member in the incoming state belongs to a group Zero currently knows about. If dstMember.GroupId has no entry in s.state.Groups, the member is referencing an unknown/stale group and the update is rejected.

Source

Thrown at dgraph/cmd/zero/zero.go:360

			return tab
		}
	}
	return nil
}

func (s *Server) createProposals(dst *pb.Group) ([]*pb.ZeroProposal, error) {
	var res []*pb.ZeroProposal
	if len(dst.Members) > 1 {
		return res, errors.Errorf("Create Proposal: Invalid group: %+v", dst)
	}

	s.RLock()
	defer s.RUnlock()
	// There is only one member. We use for loop because we don't know what the mid is.
	for mid, dstMember := range dst.Members {
		group, has := s.state.Groups[dstMember.GroupId]
		if !has {
			return res, errors.Errorf("Unknown group for member: %+v", dstMember)
		}
		srcMember, has := group.Members[mid]
		if !has {
			return res, errors.Errorf("Unknown member: %+v", dstMember)
		}
		if srcMember.Addr != dstMember.Addr ||
			srcMember.Leader != dstMember.Leader {

			proposal := &pb.ZeroProposal{
				Member: dstMember,
			}
			res = append(res, proposal)
		}
		if !dstMember.Leader {
			// Don't continue to tablets if request is not from the leader.
			return res, nil
		}
		if dst.SnapshotTs > group.SnapshotTs {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Delete the stale Alpha's postings/writedirectory state or point it at the current cluster so it re-registers with a valid group.
  2. Check /state on Zero for current group IDs and compare with the Alpha's reported group.
  3. Restart Zero and ensure its raft state is the authoritative, most recent one (don't mix old p/ and zero directories).
  4. Rebuild the cluster membership cleanly if group IDs diverged (backup, wipe, rejoin).

Example fix

// before
alpha.StartWithStaleGroupDir(oldZeroDir)
// after
alpha.CleanStaleMembershipState() // or start with an empty p dir to rejoin
groups := fetchZeroState("http://zero:6080/state")
if !groupExists(groups, alpha.GroupId) { alpha.ResetGroupId() }
alpha.Start()
Defensive patterns

Strategy: validation

Validate before calling

state, _ := http.Get("http://zero:6080/state")
if !state.Groups[alpha.GroupId].exists {
    alpha.ResetMembership(); alpha.Restart()
}

Type guard

func groupKnown(groups map[uint64]*pb.Group, id uint64) bool {
    _, ok := groups[id]
    return ok
}

Try / catch

_, err := zero.UpdateMembership(ctx, state)
if err != nil && strings.Contains(err.Error(), "Unknown group for member") {
    // stale membership: re-register Alpha
    alpha.DeregisterAndRejoin(ctx)
}

Prevention

When it happens

Trigger: An Alpha sends a membership update whose GroupId no longer exists in Zero's state — e.g., after the group was removed or Zero's state was reset while the Alpha still believes it belongs to that group.

Common situations: Zero's raft state wiped/restored from an older snapshot while Alphas keep old group IDs; leftover Alpha data directory reused after a cluster rebuild; group was removed via removeNode and the Alpha hasn't re-registered.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/51614ad7722e2140. Report an issue: GitHub.