{"record":{"id":"cea520801a788e9e","repo":"hashicorp/nomad","slug":"volume-in-use-s","errorCode":null,"errorMessage":"volume in use: %s","messagePattern":"volume in use: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nomad/state/state_store.go","lineNumber":2969,"sourceCode":"\t\t\treturn fmt.Errorf(\"volume lookup failed: %s: %v\", id, err)\n\t\t}\n\n\t\tif existing == nil {\n\t\t\treturn fmt.Errorf(\"volume not found: %s\", id)\n\t\t}\n\n\t\tvol, ok := existing.(*structs.CSIVolume)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"volume row conversion error: %s\", id)\n\t\t}\n\n\t\t// The common case for a volume deregister is when the volume is\n\t\t// unused, but we can also let an operator intervene in the case where\n\t\t// allocations have been stopped but claims can't be freed because\n\t\t// ex. the plugins have all been removed.\n\t\tif vol.InUse() {\n\t\t\tif !force || !s.volSafeToForce(txn, vol) {\n\t\t\t\treturn fmt.Errorf(\"volume in use: %s\", id)\n\t\t\t}\n\t\t}\n\n\t\tif err = txn.Delete(TableCSIVolumes, existing); err != nil {\n\t\t\treturn fmt.Errorf(\"volume delete failed: %s: %v\", id, err)\n\t\t}\n\t}\n\n\tif err := txn.Insert(\"index\", &IndexEntry{TableCSIVolumes, index}); err != nil {\n\t\treturn fmt.Errorf(\"index update failed: %v\", err)\n\t}\n\n\treturn txn.Commit()\n}\n\n// volSafeToForce checks if the any of the remaining allocations\n// are in a non-terminal state.\nfunc (s *StateStore) volSafeToForce(txn Txn, v *structs.CSIVolume) bool {","sourceCodeStart":2951,"sourceCodeEnd":2987,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L2951-L2987","documentation":"CSIVolumeDeregister refuses to remove a volume whose InUse() reports active claims (reads or writes by allocations), unless force-destroy is requested and volSafeToForce confirms all its allocations are terminal. The deregistration transaction is aborted with this error so claimed volumes cannot be silently deleted.","triggerScenarios":"`nomad volume deregister` (without -force/--force-destroy) while allocations still hold read or write claims on the volume; or with force when claims belong to non-terminal allocations, failing volSafeToForce.","commonSituations":"Operators decommissioning storage while jobs still mount it; leaked claims from dead allocations (plugin removed before claims freed); retrying deregister before the job stopped.","solutions":["Stop the jobs that mount the volume (nomad job stop) and wait for allocations to become terminal","Retry deregistration once claims are released; check claim holders with `nomad volume status <id>`","Use `nomad volume deregister -force <id>` (or --force-destroy in newer versions) only when allocations are gone but claims are stuck (e.g. plugins removed)","If claims are permanently leaked due to missing plugins, force-deregister and clean up CSI plugin jobs"],"exampleFix":"# before\nnomad volume deregister db-volume\n# Error: volume in use\n# after: stop the job first, then force if claims are stuck\nnomad job stop -purge db-job\nnomad volume deregister -force db-volume","handlingStrategy":"validation","validationCode":"// Check for active claims and stop holders before deregistering\nvol, _, err := client.CSIVolumes().Get(volumeID, nil)\nif err != nil { return err }\nif vol.InUse() {\n\treturn fmt.Errorf(\"volume %s still in use; stop jobs first\", volumeID)\n}","typeGuard":"func volumeSafeToDelete(v *api.CSIVolume) bool {\n\treturn v != nil && !v.InUse()\n}","tryCatchPattern":"if err := deregisterVolume(volID); err != nil && strings.Contains(err.Error(), \"volume in use\") {\n\t// stop claiming jobs or retry with -force after confirming terminal allocs\n}","preventionTips":["Stop mounting jobs and wait for terminal allocs before deregistering","Inspect claims via nomad volume status <id>","Use -force only for leaked claims (e.g. removed plugins)","Automate claim release in decommission runbooks"],"tags":["csi","nomad","volume-in-use","claims"],"backgroundTag":"csi-volume-in-use","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"}