{"record":{"id":"1a5e3ece1942bf49","repo":"hashicorp/nomad","slug":"could-not-claim-volume-s-w","errorCode":null,"errorMessage":"could not claim volume %s: %w","messagePattern":"could not claim volume (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/csi_hook.go","lineNumber":326,"sourceCode":"\n\t\treq := &structs.CSIVolumeClaimRequest{\n\t\t\tVolumeID:       result.stub.VolumeID,\n\t\t\tAllocationID:   c.alloc.ID,\n\t\t\tNodeID:         c.alloc.NodeID,\n\t\t\tExternalNodeID: result.stub.ExternalNodeID,\n\t\t\tClaim:          claimType,\n\t\t\tAccessMode:     request.AccessMode,\n\t\t\tAttachmentMode: request.AttachmentMode,\n\t\t\tWriteRequest: structs.WriteRequest{\n\t\t\t\tRegion:    c.alloc.Job.Region,\n\t\t\t\tNamespace: c.alloc.Job.Namespace,\n\t\t\t\tAuthToken: c.nodeSecret,\n\t\t\t},\n\t\t}\n\n\t\tresp, err := c.claimWithRetry(req)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not claim volume %s: %w\", req.VolumeID, err)\n\t\t}\n\t\tif resp.Volume == nil {\n\t\t\treturn fmt.Errorf(\"Unexpected nil volume returned for ID: %v\", request.Source)\n\t\t}\n\n\t\tresult.volume = resp.Volume\n\n\t\t// populate data we'll write later to disk\n\t\tresult.stub.VolumeID = resp.Volume.ID\n\t\tresult.stub.VolumeNamespace = resp.Volume.Namespace\n\t\tresult.stub.VolumeExternalID = resp.Volume.RemoteID()\n\t\tresult.stub.PluginID = resp.Volume.PluginID\n\t\tresult.publishContext = resp.PublishContext\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/csi_hook.go#L308-L344","documentation":"During Prerun, claimVolumes sends a CSIVolumeClaimRequest to the Nomad server via claimWithRetry; the server marks the volume claimed by this allocation and runs controller publish. Any error from that RPC (wrapped with %w) aborts allocation startup. This is the error boundary for server-side claim failures such as volume-not-found, claim conflicts, or RPC/network failures.","triggerScenarios":"claimWithRetry returns an error for the volume identified by req.VolumeID: the volume was deregistered, the server rejected the claim (e.g. incompatible access mode, max claims reached, garbage-collected volume), the CSI plugin/controller is unhealthy, or the client cannot reach the server.","commonSituations":"Volume was GC'd or deregistered between job submission and allocation; too many readers/writers already claim the volume for its access mode; CSI controller plugin is down; node lost registration with the external storage system; server RPC errors/timeouts.","solutions":["Read the wrapped (%w) inner error to identify the root cause — volume missing, claim conflict, or RPC failure.","Verify the volume still exists with `nomad volume status <volume_id>` and re-register it if it was GC'd or deregistered.","Check the CSI plugin/controller health (`nomad plugin status`) and fix the plugin or its external storage backend.","Check access-mode compatibility: a single-writer volume cannot be claimed by multiple allocations; reduce claim count or change access_mode.","Retry allocation placement once server/plugin connectivity is restored (Nomad's claimWithRetry already retries transient errors)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check the volume exists and is claimable\nvol, err := client.Volumes().Info(volumeID, nil)\nif err != nil || vol == nil {\n    return fmt.Errorf(\"volume %s not registered or inaccessible\", volumeID)\n}","typeGuard":"func volumeClaimed(vol *api.CSIVolume) bool { return vol != nil && vol.ID != \"\" }","tryCatchPattern":"err := allocRunner.Prerun()\nvar claimErr *fmt.wrapError // inspect via errors.Unwrap chain\nif err != nil && strings.Contains(err.Error(), \"could not claim volume\") {\n    inner := errors.Unwrap(err)\n    log.Printf(\"claim failed: %v; check volume status and plugin health\", inner)\n    // reschedule after fixing volume/plugin state\n}","preventionTips":["Monitor CSI plugins with nomad plugin status before deploying volume workloads.","Set appropriate access_mode/access_count so claims don't conflict.","Avoid GC/deregistration of in-use volumes.","Ensure server connectivity and stable regions/namespaces in the jobspec."],"tags":["nomad","csi","volumes","rpc"],"backgroundTag":"csi-volume-claim-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}