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, nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Re-register the CSI plugin (restart plugin task on clients) so the ID exists again
- List `nomad volume status <id>` to confirm vol.PluginID and compare with `nomad plugin status`
- Free/deregister stale volumes referencing the missing plugin to clear claims
- 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
- Never deregister a CSI plugin while volumes still have claims
- Check `nomad volume status` claim list before plugin GC
- Keep plugin IDs stable across upgrades
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
- %w: %v
- no such volume
- error parsing: root should be an object
- cannot specify Accessor ID
- missing accessor ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1bdfc33120d17a73.
Report an issue: GitHub.