{"record":{"id":"6210115c92ce701b","repo":"hashicorp/nomad","slug":"errvolumenameexists","errorCode":"ErrVolumeNameExists","errorMessage":"volume name already exists on this node","messagePattern":"volume name already exists on this node","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/hostvolumemanager/host_volumes.go","lineNumber":23,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/hashicorp/go-hclog\"\n\t\"github.com/hashicorp/go-multierror\"\n\tcstructs \"github.com/hashicorp/nomad/client/structs\"\n\t\"github.com/hashicorp/nomad/helper\"\n\t\"github.com/hashicorp/nomad/nomad/structs\"\n)\n\nvar (\n\tErrPluginNotExists     = errors.New(\"no such plugin\")\n\tErrPluginNotExecutable = errors.New(\"plugin not executable\")\n\tErrVolumeNameExists    = errors.New(\"volume name already exists on this node\")\n)\n\n// HostVolumeStateManager manages the lifecycle of volumes in client state.\ntype HostVolumeStateManager interface {\n\tPutDynamicHostVolume(*cstructs.HostVolumeState) error\n\tGetDynamicHostVolumes() ([]*cstructs.HostVolumeState, error)\n\tDeleteDynamicHostVolume(string) error\n}\n\n// Config is used to configure a HostVolumeManager.\ntype Config struct {\n\t// PluginDir is where external plugins may be found.\n\tPluginDir string\n\n\t// VolumesDir is where plugins should place the directory\n\t// that will later become a volume's HostPath\n\tVolumesDir string\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/hostvolumemanager/host_volumes.go#L5-L41","documentation":"ErrVolumeNameExists is returned by the dynamic host volume name lock when two concurrent volume creations attempt to claim the same volume name on the same node. Nomad enforces that volume names are unique per node, so the second claim is rejected. It signals contention rather than a configuration error.","triggerScenarios":"Two goroutines/allocations concurrently calling the dynamic host volume creation flow whose lock's LoadOrStore finds the name already mapped to a different volume ID; also asserted in host_volumes_test.go via must.ErrorIs(err, ErrVolumeNameExists).","commonSituations":"Retry storms or duplicate job submissions creating dynamic host volumes with the same name concurrently; a stale/retried volume-create request racing a successful first attempt.","solutions":["Retry with a distinct volume name or let the scheduler generate a unique name","Check whether an existing dynamic host volume with that name already satisfies the request and reuse it","Serialize creation through one request path instead of concurrent duplicate calls","Investigate duplicate allocations/jobs issuing the same volume name"],"exampleFix":"// before\nname := \"shared-volume\" // concurrent creates collide\n// after\nname := fmt.Sprintf(\"shared-volume-%s\", uuid.Generate()) // or reuse existing volume","handlingStrategy":"retry","validationCode":"// before creating, check the name isn't already claimed\nif _, err := state.GetDynamicHostVolume(name); err == nil {\n    return nil // already exists, reuse\n}","typeGuard":null,"tryCatchPattern":"created, err := lock(name, id)\nif errors.Is(err, ErrVolumeNameExists) {\n    // pick a new unique name or reuse existing volume, then retry\n    return retryWithNewName()\n}","preventionTips":["Generate unique volume names (suffix with alloc ID or UUID)","Avoid duplicate concurrent volume-create requests for the same name","Treat ErrVolumeNameExists as idempotent-success when the existing volume matches","Serialize dynamic volume creation per node"],"tags":["go","host-volumes","concurrency"],"backgroundTag":"resource-already-exists","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"}