{"record":{"id":"1239c4c758d7c974","repo":"dgraph-io/dgraph","slug":"s-s-1239c4","errorCode":null,"errorMessage":"%s: %s","messagePattern":"%s: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/admin/state.go","lineNumber":46,"sourceCode":"\tMaxTxnTs   uint64         `json:\"maxTxnTs,omitempty\"`\n\tMaxRaftId  uint64         `json:\"maxRaftId,omitempty\"`\n\tRemoved    []*pb.Member   `json:\"removed,omitempty\"`\n\tCid        string         `json:\"cid,omitempty\"`\n\tNamespaces []uint64       `json:\"namespaces,omitempty\"`\n}\n\ntype clusterGroup struct {\n\tId         uint32       `json:\"id,omitempty\"`\n\tMembers    []*pb.Member `json:\"members,omitempty\"`\n\tTablets    []*pb.Tablet `json:\"tablets,omitempty\"`\n\tSnapshotTs uint64       `json:\"snapshotTs,omitempty\"`\n\tChecksum   uint64       `json:\"checksum,omitempty\"`\n}\n\nfunc resolveState(ctx context.Context, q schema.Query) *resolve.Resolved {\n\tresp, err := (&edgraph.Server{}).State(ctx)\n\tif err != nil {\n\t\treturn resolve.EmptyResult(q, errors.Errorf(\"%s: %s\", x.Error, err.Error()))\n\t}\n\n\t// unmarshal it back to MembershipState proto in order to map to graphql response\n\tvar ms pb.MembershipState\n\tif err := protojson.Unmarshal(resp.GetJson(), &ms); err != nil {\n\t\treturn resolve.EmptyResult(q, err)\n\t}\n\n\tns, _ := x.ExtractNamespace(ctx)\n\t// map to graphql response structure. Only superadmin can list the namespaces.\n\tstate := convertToGraphQLResp(&ms, ns == x.RootNamespace)\n\tb, err := json.Marshal(state)\n\tif err != nil {\n\t\treturn resolve.EmptyResult(q, err)\n\t}\n\tvar resultState map[string]interface{}\n\terr = schema.Unmarshal(b, &resultState)\n\tif err != nil {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/admin/state.go#L28-L64","documentation":"resolveState calls the edgraph Server's State method to fetch the cluster membership state; any error from that call is re-wrapped as '<x.Error>: <detail>' and returned as an empty GraphQL result. The wrapper preserves the underlying detail (Raft/health check failure) so the suffix tells you what actually broke. This is about the /state-equivalent admin GraphQL query failing at the server layer.","triggerScenarios":"Querying state via the admin GraphQL API when the internal Server.State call fails: the node is not part of a healthy cluster, Raft has no leader, the node is still starting up, or internal gRPC connections to Zero/other Alphas are down.","commonSituations":"Querying a freshly restarted Alpha before it rejoining the group, Zero down or unreachable (bad zeroDir/--zero flags), network partitions in Kubernetes, or hitting an Alpha that was removed from the cluster.","solutions":["Read the text after the prefix for the root cause (e.g. no connected Zero, raft: no leader) and address it directly.","Verify Zero nodes are running and reachable from this Alpha (check --zero addresses, DNS, ports 5080/6080).","Wait for the Alpha to finish joining/replaying and re-run the state query.","Use curl on /health and /state HTTP endpoints to triage cluster membership.","If the node was removed from the cluster, re-add it or point clients at a healthy member."],"exampleFix":"// before: querying an Alpha whose Zero is down\nquery { state { ... } }  // -> \"x: ...connection refused...\"\n// after: restore Zero, then\nquery { state { groups { id } } }","handlingStrategy":"retry","validationCode":"// Pre-check cluster health before the state query\nconst health = await fetch('http://alpha:8080/health').then(r => r.json());\nif (!health.every(h => h.status === 'healthy')) throw new Error('cluster unhealthy; skip state query');","typeGuard":null,"tryCatchPattern":"try {\n  return await gql(stateQuery);\n} catch (e) {\n  if (String(e.message).includes('x:')) {\n    const detail = e.message.split(': ').slice(1).join(': ');\n    if (/connection refused|no leader|unavailable/i.test(detail)) {\n      await sleep(backoff);\n      return retry(() => gql(stateQuery), 3); // transient cluster state\n    }\n  }\n  throw e;\n}","preventionTips":["Wait for Alphas to report healthy after restarts before querying state","Keep --zero addresses correct and reachable from every Alpha","Monitor Raft leadership; expect failures during elections","Use /health and /state HTTP endpoints as pre-flight checks","Alert on Zero connectivity so state queries never run blind"],"tags":["graphql","cluster","raft","admin-api","state"],"backgroundTag":"cluster-state-unavailable","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}