{"record":{"id":"b5bed827607fe7d4","repo":"hashicorp/nomad","slug":"job-q-is-in-nonexistent-node-pool-q","errorCode":null,"errorMessage":"job %q is in nonexistent node pool %q","messagePattern":"job %q is in nonexistent node pool %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/job_endpoint_hook_node_pool.go","lineNumber":30,"sourceCode":"// jobNodePoolValidatingHook is an admission hook that ensures the job has valid\n// node pool configuration.\ntype jobNodePoolValidatingHook struct {\n\tsrv *Server\n}\n\nfunc (j jobNodePoolValidatingHook) Name() string {\n\treturn \"node-pool-validation\"\n}\n\nfunc (j jobNodePoolValidatingHook) Validate(job *structs.Job) ([]error, error) {\n\tpoolName := job.NodePool\n\n\tpool, err := j.srv.State().NodePoolByName(nil, poolName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif pool == nil {\n\t\treturn nil, fmt.Errorf(\"job %q is in nonexistent node pool %q\", job.ID, poolName)\n\t}\n\n\treturn j.enterpriseValidation(job, pool)\n}\n","sourceCodeStart":12,"sourceCodeEnd":35,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/job_endpoint_hook_node_pool.go#L12-L35","documentation":"The job endpoint validation hook verifies that every job references an existing node pool. It looks the pool up in state via NodePoolByName; if the lookup succeeds but returns nil, the job's cluster/nodes pool does not exist and registration is rejected.","triggerScenarios":"Calling the Job.Register/Validate API (or nomad job run) with a job whose node pool (job { node_pool = \"...\" }) names a pool that has not been created via the NodePools API.","commonSituations":"Typo in node_pool name; applying a job before the node pool Terraform/API provisioning; copying jobs between clusters where the target cluster lacks the pool; enterprise multi-cluster deployments where one cluster has the pool and another doesn't.","solutions":["Create the node pool first: nomad node pool apply <name> (or the NodePools API), then submit the job.","Fix the node_pool value in the job to an existing pool (nomad node pool list).","If the job should run in the default pool, remove the node_pool stanza so it defaults to \"default\"."],"exampleFix":"// before\njob \"web\" {\n  node_pool = \"prod-eu\" # does not exist\n}\n// after\n# create it first: nomad node pool apply prod-eu\njob \"web\" {\n  node_pool = \"prod-eu\"\n}","handlingStrategy":"validation","validationCode":"// before submitting\npools, _, err := client.NodePools().List(nil)\nif err != nil { return err }\nwant := job.TaskGroups[0].NodePool // or job-level node_pool\nfound := false\nfor _, p := range pools {\n  if p.Name == want { found = true }\n}\nif !found { return fmt.Errorf(\"node pool %q not found; create it with `nomad node pool apply %s`\", want, want) }","typeGuard":"func nodePoolExists(pools []*api.NodePool, name string) bool {\n\tfor _, p := range pools {\n\t\tif p.Name == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":"// golang\n_, _, err := client.Jobs().Register(job, nil)\nif err != nil && strings.Contains(err.Error(), \"nonexistent node pool\") {\n\t// create the pool then retry once\n}\n// nomad CLI: check `nomad node pool list` before `nomad job run`","preventionTips":["Run nomad node pool list and cross-check job node_pool values in CI.","Provision node pools (Terraform/API) before deploying jobs.","Default to the \"default\" pool unless the pool is guaranteed to exist.","Keep pool names in shared config variables to avoid typos across clusters."],"tags":["nomad","node-pool","job-validation"],"backgroundTag":"nonexistent-node-pool","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"}