{"record":{"id":"74f81b5ec5470225","repo":"hashicorp/nomad","slug":"cluster-id-not-ready-yet","errorCode":null,"errorMessage":"cluster ID not ready yet","messagePattern":"cluster ID not ready yet","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nomad/server.go","lineNumber":2304,"sourceCode":"\ts.clusterIDLock.Lock()\n\tdefer s.clusterIDLock.Unlock()\n\n\t// try to load the cluster ID from state store\n\tfsmState := s.fsm.State()\n\texistingMeta, err := fsmState.ClusterMetadata(nil)\n\tif err != nil {\n\t\ts.logger.Named(\"core\").Error(\"failed to get cluster ID\", \"error\", err)\n\t\treturn structs.ClusterMetadata{}, err\n\t}\n\n\t// got the cluster ID from state store, cache that and return it\n\tif existingMeta != nil && existingMeta.ClusterID != \"\" {\n\t\treturn *existingMeta, nil\n\t}\n\n\t// if we are not the leader, nothing more we can do\n\tif !s.IsLeader() {\n\t\treturn structs.ClusterMetadata{}, errors.New(\"cluster ID not ready yet\")\n\t}\n\n\t// we are the leader, try to generate the ID now\n\tgeneratedMD, err := s.generateClusterMetadata()\n\tif err != nil {\n\t\treturn structs.ClusterMetadata{}, err\n\t}\n\n\treturn generatedMD, nil\n}\n\nfunc (s *Server) isSingleServerCluster() bool {\n\treturn s.config.BootstrapExpect == 1\n}\n\n// peersInfoContent is used to help operators understand what happened to the\n// peers.json file. This is written to a file called peers.info in the same\n// location.","sourceCodeStart":2286,"sourceCodeEnd":2322,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/server.go#L2286-L2322","documentation":"ClusterMetadata (cluster ID) generation only happens on the leader. If no persisted cluster ID exists yet and the server handling the request is not the leader, there is nothing it can do, so it returns \"cluster ID not ready yet\". Callers must retry against the leader once the ID is generated.","triggerScenarios":"Querying cluster metadata (e.g. via state store access used by RPCs like ClusterMetadata or replication paths) on a follower server before the leader has generated and persisted the cluster ID, such as immediately after forming a new cluster or restoring from a state where cluster ID is absent.","commonSituations":"New cluster bootstrapping; right after leader election where the new leader has not yet finished generateClusterMetadata; clients hitting a non-leader node in multi-server setups.","solutions":["Retry the request after a short backoff; it succeeds once the leader generates the cluster ID","Route the request to the leader (use nomad operator api /v1/status/leader to find it, or ensure the client targets the leader address)","Verify cluster health and that a leader exists (`nomad server members`) before depending on cluster ID"],"exampleFix":"// before\nmeta := server.ClusterMetadata()\nuseClusterID(meta.ID)\n// after (retry until ready)\nvar md structs.ClusterMetadata\nvar err error\nfor i := 0; i < 30; i++ {\n    md, err = server.ClusterMetadata()\n    if err == nil { break }\n    if !strings.Contains(err.Error(), \"not ready yet\") { return err }\n    time.Sleep(time.Second)\n}","handlingStrategy":"retry","validationCode":"// Confirm a leader exists before depending on cluster ID\nfor _, m := range client.Agent().Members() {\n    if m.Leader { break }\n}\n// else wait for leader election first","typeGuard":null,"tryCatchPattern":"meta, err := getClusterMetadata()\nif err != nil && strings.Contains(err.Error(), \"cluster ID not ready yet\") {\n    time.Sleep(2 * time.Second)\n    meta, err = getClusterMetadata() // or target the leader\n}","preventionTips":["Delay cluster-ID-dependent work until after leader election","Target the leader node for metadata queries in multi-server clusters","Add backoff retries around post-bootstrap operations"],"tags":["nomad","raft","cluster-metadata","timing"],"backgroundTag":"cluster-not-ready","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}