{"record":{"id":"2a481c27ec78b6b0","repo":"hashicorp/nomad","slug":"node-pool-q-has-non-terminal-jobs-in-regions-v","errorCode":null,"errorMessage":"node pool %q has non-terminal jobs in regions: %v","messagePattern":"node pool %q has non-terminal jobs in regions: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/node_pool_endpoint.go","lineNumber":280,"sourceCode":"\n\t// Validate request.\n\tif len(args.Names) == 0 {\n\t\treturn structs.NewErrRPCCodedf(http.StatusBadRequest, \"must specify at least one node pool to delete\")\n\t}\n\tif slices.Contains(args.Names, \"\") {\n\t\treturn structs.NewErrRPCCodedf(http.StatusBadRequest, \"node pool name is empty\")\n\t}\n\n\t// Verify that the node pools we're deleting do not have nodes or\n\t// non-terminal jobs in this region or in any federated region.\n\tvar mErr multierror.Error\n\tfor _, name := range args.Names {\n\t\tregionsWithNonTerminal, regionsWithNodes, err := n.nodePoolRegionsInUse(args.AuthToken, name)\n\t\tif err != nil {\n\t\t\t_ = multierror.Append(&mErr, err)\n\t\t}\n\t\tif len(regionsWithNonTerminal) != 0 {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\n\t\t\t\t\"node pool %q has non-terminal jobs in regions: %v\", name, regionsWithNonTerminal))\n\t\t}\n\t\tif len(regionsWithNodes) != 0 {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\n\t\t\t\t\"node pool %q has nodes in regions: %v\", name, regionsWithNodes))\n\t\t}\n\t}\n\n\tif err := mErr.ErrorOrNil(); err != nil {\n\t\treturn err\n\t}\n\n\t// Delete via Raft.\n\t_, index, err := n.srv.raftApply(structs.NodePoolDeleteRequestType, args)\n\tif err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/node_pool_endpoint.go#L262-L298","documentation":"DeleteNodePools refuses to delete a node pool that still has non-terminal (running/pending) jobs in any region. The endpoint checks via nodePoolRegionsInUse and reports which regions block the deletion, appended to a multierror.","triggerScenarios":"`nomad node pool delete <pool>` or DELETE /v1/node/pools where jobs assigned to the pool are still in pending or running state in one or more regions (enterprise multi-region setups).","commonSituations":"Operators cleaning up pools without first stopping/purging the jobs running in them; multi-region deployments where a job in a remote region is easily overlooked.","solutions":["List and stop/purge all jobs in the pool: `nomad job list` / `nomad job stop -purge <job>` in each listed region","Re-run the delete once all jobs in the pool are terminal (dead/complete)","If jobs are orphaned, force-purge them via the API with the correct region","Move jobs to another node pool before deleting the pool"],"exampleFix":"// before\n$ nomad node pool delete prod\nError: node pool \"prod\" has non-terminal jobs in regions: [us-east]\n// after\n$ nomad job stop -purge -region us-east webapp\n$ nomad node pool delete prod","handlingStrategy":"validation","validationCode":"jobs, _ := client.Jobs().List(nil)\nfor _, j := range jobs {\n    if *j.NodePool == poolName && j.Status != \"dead\" && j.Status != \"complete\" {\n        return fmt.Errorf(\"job %s still non-terminal in pool %s\", j.ID, poolName)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := client.NodePools().Delete([]string{poolName}, wr)\nif err != nil && strings.Contains(err.Error(), \"non-terminal jobs\") {\n    // stop/purge listed jobs, then retry\n}","preventionTips":["List pool jobs before any pool deletion","Script job stop -purge across all regions for pool cleanup","Check enterprise multi-region jobs, not just the local region","Document pool teardown runbooks including job purge steps"],"tags":["nomad","node-pools","jobs","multi-region"],"backgroundTag":"resource-in-use","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"}