hashicorp/nomad · error
namespace %q has non-terminal jobs in regions: %v
Error message
namespace %q has non-terminal jobs in regions: %v
What it means
Before deleting a namespace, Nomad checks every region for non-terminal (pending/running) jobs and allocations tied to that namespace via nonTerminalObjectsInNS. If any region still reports non-terminal objects, the delete is aborted with this error naming the offending regions. This prevents removing a namespace that still has live workloads.
Source
Thrown at nomad/namespace_endpoint.go:207
for _, region := range regions {
if region == thisRegion {
continue
}
if remoteCheckFunc != nil {
remoteTerminal, err := remoteCheckFunc(authToken, namespace, region)
if err != nil {
return err
}
if !remoteTerminal {
terminal = append(terminal, region)
}
}
}
if len(terminal) != 0 {
return fmt.Errorf(errorMsg, namespace, terminal)
}
return nil
}
// namespaceTerminalJobsLocally returns true if the namespace contains only
// terminal jobs in the local region.
func (n *Namespace) namespaceTerminalJobsLocally(namespace string, snap *state.StateSnapshot) (bool, error) {
iter, err := snap.JobsByNamespace(nil, namespace, state.SortDefault)
if err != nil {
return false, err
}
for {
raw := iter.Next()
if raw == nil {
break
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Stop or purge all jobs in the namespace in every listed region (nomad job stop -purge).
- Verify allocations are terminal (nomad status <job>); rebalance or clean orphaned allocs on dead nodes.
- Retry the namespace delete once all regions report only terminal objects.
- Check other regions explicitly if running a multi-region/federated cluster.
Example fix
// before
client.Namespaces().Delete(&api.NamespaceDeleteRequest{Namespaces: []string{"prod"}}) // fails: jobs still running
// after
for _, job := range jobsInNamespace("prod") {
client.Jobs().Deregister(job.ID, true, &api.WriteOptions{Namespace: "prod"}) // purge
}
client.Namespaces().Delete(&api.NamespaceDeleteRequest{Namespaces: []string{"prod"}}) Defensive patterns
Strategy: validation
Validate before calling
jobs, _, _ := client.Jobs().List(&api.QueryOptions{Namespace: ns})
for _, j := range jobs {
if j.Status != "dead" { return fmt.Errorf("job %s still %s", j.ID, j.Status) }
}
_, err := client.Namespaces().Delete(&api.NamespaceDeleteRequest{Namespaces: []string{ns}}) Try / catch
_, err := client.Namespaces().Delete(req)
if err != nil && strings.Contains(err.Error(), "non-terminal") {
// purge remaining jobs in each listed region, then retry once
} Prevention
- Purge (not just stop) all jobs before deleting a namespace.
- Check jobs in every region, not just the local one.
- Watch for orphaned allocs on down nodes and clean them up.
- Automate: stop -> wait for terminal -> delete namespace.
When it happens
Trigger: Calling Namespace.Delete while jobs in the namespace are pending/running in one or more regions; orphaned non-terminal allocations on dead nodes; leftover workloads after a failed cleanup.
Common situations: Deleting namespaces during cluster teardown while a job is still running; multi-region deployments where a remote region still runs workloads; stuck allocations from a down node that never reached terminal state.
Related errors
- must specify at least one namespace to delete
- can not delete default namespace
- error parsing: root should be an object
- missing policy name
- cannot specify Accessor ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6e37224e35b0216d.
Report an issue: GitHub.