hashicorp/nomad · error

default namespace can not be deleted

Error message

default namespace can not be deleted

What it means

Nomad's state store rejects deletion of the built-in "default" namespace in DeleteNamespace. The default namespace is a system-reserved namespace that jobs and other objects fall back to, so it must always exist. Any DeleteNamespace RPC targeting it fails immediately inside the state-store transaction.

Source

Thrown at nomad/state/state_store.go:7128

// DeleteNamespaces is used to remove a set of namespaces
func (s *StateStore) DeleteNamespaces(index uint64, names []string) error {
	txn := s.db.WriteTxn(index)
	defer txn.Abort()

	for _, name := range names {
		// Lookup the namespace
		existing, err := txn.First(TableNamespaces, "id", name)
		if err != nil {
			return fmt.Errorf("namespace lookup failed: %v", err)
		}
		if existing == nil {
			return fmt.Errorf("namespace not found")
		}

		ns := existing.(*structs.Namespace)
		if ns.Name == structs.DefaultNamespace {
			return fmt.Errorf("default namespace can not be deleted")
		}

		// Ensure that the namespace doesn't have any non-terminal jobs
		iter, err := s.jobsByNamespaceImpl(nil, name, txn, SortDefault)
		if err != nil {
			return err
		}

		for {
			raw := iter.Next()
			if raw == nil {
				break
			}
			job := raw.(*structs.Job)

			if job.Status != structs.JobStatusDead {
				return fmt.Errorf("namespace %q contains at least one non-terminal job %q. "+
					"All jobs must be terminal in namespace before it can be deleted", name, job.ID)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Exclude structs.DefaultNamespace ("default") from any automated namespace deletion list.
  2. Delete only namespaces you explicitly created.
  3. If the goal is to remove workload from default, move jobs to a new namespace instead of deleting default.

Example fix

// before
for _, ns := range namespaces {
    client.Namespaces().Delete(ns.Name, nil)
}
// after
for _, ns := range namespaces {
    if ns.Name != "default" {
        client.Namespaces().Delete(ns.Name, nil)
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if ns == "default" {
    return fmt.Errorf("refusing to delete reserved namespace %q", ns)
}
return client.Namespaces().Delete(ns, nil)

Type guard

func isReservedNamespace(name string) bool { return name == "default" }

Prevention

When it happens

Trigger: Calling the Namespace Delete API (DELETE /v1/namespace/default), `nomad namespace delete default`, or a `namespace_delete` job/agent action naming the default namespace.

Common situations: Cleanup scripts that iterate all namespaces and delete each one; Terraform/automation that manages namespaces and tries to converge by removing the default; operators mistaking default for an unused namespace.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/0751cbb7a76df823. Report an issue: GitHub.