hashicorp/nomad · error

missing accessor ID

Error message

missing accessor ID

What it means

The target node is registered in Nomad but has no CSINodePlugins entry (or nil NodeInfo) for the volume's PluginID — the CSI node plugin is not running or has not fingerprinted on that client. lookupExternalNodeID needs the plugin-reported external node ID to talk to the storage controller.

Source

Thrown at api/acl.go:147

// Create is used to create a token with server-generated AccessorID and
// SecretID. Use Upload to create a token with pre-specified IDs.
func (a *ACLTokens) Create(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
	if token.AccessorID != "" {
		return nil, nil, errors.New("cannot specify Accessor ID")
	}
	var resp ACLToken
	wm, err := a.client.put("/v1/acl/token", token, &resp, q)
	if err != nil {
		return nil, nil, err
	}
	return &resp, wm, nil
}

// Upload is used to create a client token with pre-specified AccessorID and
// SecretID. Management tokens cannot be uploaded and must be created with Create.
func (a *ACLTokens) Upload(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
	if token.AccessorID == "" {
		return nil, nil, errors.New("missing accessor ID")
	}
	if token.SecretID == "" {
		return nil, nil, errors.New("missing secret ID")
	}
	if token.Type == "management" {
		return nil, nil, errors.New("cannot upload management tokens")
	}
	var resp ACLToken
	wm, err := a.client.put("/v1/acl/token/"+token.AccessorID, token, &resp, q)
	if err != nil {
		return nil, nil, err
	}
	return &resp, wm, nil
}

// Update is used to update an existing token
func (a *ACLTokens) Update(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) {
	if token.AccessorID == "" {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check plugin health on the client: nomad node status <id> -verbose and look for the CSI plugin fingerprint
  2. Inspect the plugin alloc logs (nomad alloc logs) for fingerprint/socket errors
  3. Fix plugin task requirements (privileged:true, mount propagation, host volumes) so csi.sock is exposed
  4. Wait/retry — if the plugin merely hasn't fingerprinted yet, the claim runner retries later
  5. Confirm vol.PluginID matches the ID the node plugin registered with

Example fix

// before: CSI task without required privileges
 task "ebs-plugin" {
   driver = "docker"
   config { image = "amazon/aws-ebs-csi-driver" }
   csi_plugin { id = "aws-ebs" type = "node" mount_dir = "/csi" }
 }
// after
 task "ebs-plugin" {
   driver = "docker"
   config {
     image = "amazon/aws-ebs-csi-driver"
     privileged = true
     mount_types = ["bind"]
   }
   csi_plugin { id = "aws-ebs" type = "node" mount_dir = "/csi" }
 }
Defensive patterns

Strategy: validation

Validate before calling

node, _, _ := client.Nodes().Info(nodeID, nil)
info, ok := node.CSINodePlugins[pluginID]
if !ok || info.NodeInfo == nil {
    // plugin not fingerprinted on client: wait or fix plugin task
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to find storage provider info") {
    // wait for fingerprinting, check plugin alloc logs, retry
    waitForPluginFingerprint(nodeID, pluginID)
}

Prevention

When it happens

Trigger: controllerPublishVolume/unpublish while the node plugin task is crashed/pending, the plugin hasn't completed fingerprinting yet, the plugin's NodeIDLabel is unset, or the plugin is registered with a different PluginID than the volume references.

Common situations: Client just started and CSI plugin still initializing; plugin job failed due to missing privileges (--privileged, mount propagation) or missing csi.sock; plugin deregistered from node but volume still scheduled there; timing race right after allocation.

Related errors


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