hashicorp/nomad · error

namespace %q contains at least one CSI volume %q. All CSI vo

Error message

namespace %q contains at least one CSI volume %q. All CSI volumes in namespace must be deleted before it can be deleted

What it means

DeleteNamespace checks for CSI volumes registered in the namespace and refuses deletion if any exist. CSI volume objects must be explicitly deregistered/deleted first; the error names the volume ID that blocks deletion.

Source

Thrown at nomad/state/state_store.go:7157

			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)
			}
		}

		vIter, err := s.csiVolumesByNamespaceImpl(txn, nil, name, "")
		if err != nil {
			return err
		}
		rawVol := vIter.Next()
		if rawVol != nil {
			vol := rawVol.(*structs.CSIVolume)
			return fmt.Errorf("namespace %q contains at least one CSI volume %q. "+
				"All CSI volumes in namespace must be deleted before it can be deleted", name, vol.ID)
		}

		varIter, err := s.getVariablesByNamespaceImpl(txn, nil, name)
		if err != nil {
			return err
		}
		if varIter.Next() != nil {
			// unlike job/volume, don't show the path here because the user may
			// not have List permissions on the vars in this namespace
			return fmt.Errorf("namespace %q contains at least one variable. "+
				"All variables in namespace must be deleted before it can be deleted", name)
		}

		// Delete the namespace
		if err := txn.Delete(TableNamespaces, existing); err != nil {
			return fmt.Errorf("namespace deletion failed: %v", err)
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Deregister the volume: `nomad volume deregister -namespace <ns> <volume-id>` (or `nomad volume delete` for per-alloc CSI volumes), then retry namespace deletion.
  2. Ensure the storage plugin/node providing the volume is drained so claims can be released.
  3. Delete any jobs claiming the volume first, since claimed volumes may not be deletable.

Example fix

# before
nomad namespace delete storage-team
# after
nomad volume deregister -namespace storage-team <volume-id>
nomad namespace delete storage-team
Defensive patterns

Strategy: validation

Validate before calling

vols, _, _ := client.CSIVolumes().List(&nomad.QueryOptions{Namespace: ns})
if len(vols) > 0 {
    return fmt.Errorf("%d CSI volumes still registered in %s", len(vols), ns)
}

Try / catch

if strings.Contains(err.Error(), "CSI volume") {
    // deregister the volume named in the message, then retry
}

Prevention

When it happens

Trigger: DELETE /v1/namespace/<name> while a CSI volume (from a `volume` block or CSI plugin registration) is still registered in that namespace.

Common situations: Decommissioning a namespace that used host/CSI storage; volumes left behind after jobs were stopped because CSI volumes are not garbage-collected with jobs.

Related errors


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