hashicorp/nomad · error

missing policy name

Error message

missing policy name

What it means

controllerUnpublishVolume found no CSI plugin in the Nomad state store matching vol.PluginID. The volume references a plugin that has been deregistered or never registered, so the detach cannot proceed. Nomad returns this instead of silently skipping the unpublish.

Source

Thrown at api/acl.go:36

// ACLPolicies returns a new handle on the ACL policies.
func (c *Client) ACLPolicies() *ACLPolicies {
	return &ACLPolicies{client: c}
}

// List is used to dump all of the policies.
func (a *ACLPolicies) List(q *QueryOptions) ([]*ACLPolicyListStub, *QueryMeta, error) {
	var resp []*ACLPolicyListStub
	qm, err := a.client.query("/v1/acl/policies", &resp, q)
	if err != nil {
		return nil, nil, err
	}
	return resp, qm, nil
}

// Upsert is used to create or update a policy
func (a *ACLPolicies) Upsert(policy *ACLPolicy, q *WriteOptions) (*WriteMeta, error) {
	if policy == nil || policy.Name == "" {
		return nil, errors.New("missing policy name")
	}
	wm, err := a.client.put("/v1/acl/policy/"+policy.Name, policy, nil, q)
	if err != nil {
		return nil, err
	}
	return wm, nil
}

// Delete is used to delete a policy
func (a *ACLPolicies) Delete(policyName string, q *WriteOptions) (*WriteMeta, error) {
	if policyName == "" {
		return nil, errors.New("missing policy name")
	}
	wm, err := a.client.delete("/v1/acl/policy/"+policyName, nil, nil, q)
	if err != nil {
		return nil, err
	}
	return wm, nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Re-register the CSI plugin (restart plugin task on clients) so the ID exists again
  2. List `nomad volume status <id>` to confirm vol.PluginID and compare with `nomad plugin status`
  3. Free/deregister stale volumes referencing the missing plugin to clear claims
  4. If the claim is orphaned, manually set claim state to ReadyToFree via state tooling or delete the volume

Example fix

// before: deregistering plugin with live volume claims
nomad plugin status csi-ebs-plugin  # check controllers
nomad system gc                     # wrong: drops plugin while claims exist
// after: release claims first
nomad volume status myvol           # confirm no claims
nomad volume deregister -force myvol
# then deregister the plugin
Defensive patterns

Strategy: validation

Validate before calling

// check plugin exists before deregistering or using volumes
plugins, _, _ := client.CSIPlugins().List(nil)
var found bool
for _, p := range plugins { if p.ID == vol.PluginID { found = true } }
if !found { /* re-register plugin or release claims first */ }

Try / catch

if err := unpublish(vol); err != nil && strings.Contains(err.Error(), "no such plugin") {
    // plugin deregistered: re-register plugin or force-release the claim
    requeueOrReleaseClaim(vol)
}

Prevention

When it happens

Trigger: Unpublish (claim release, job stop, node drain) on a volume whose plugin was deregistered via `nomad plugin status`/CSIPlugin.Deregister, or whose PluginID was misspelled/vanished after plugin GC while claims still exist.

Common situations: Operators deregister a CSI plugin that still has volumes with outstanding claims; changing a volume spec's plugin ID; upgrading and re-registering a plugin under a new ID while old volumes persist.

Related errors


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