hashicorp/nomad · warning
ErrVolumeNameExists
ErrVolumeNameExists
Error message
volume name already exists on this node
What it means
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.
Source
Thrown at client/hostvolumemanager/host_volumes.go:23
import (
"context"
"errors"
"fmt"
"os"
"sync"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-multierror"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/nomad/nomad/structs"
)
var (
ErrPluginNotExists = errors.New("no such plugin")
ErrPluginNotExecutable = errors.New("plugin not executable")
ErrVolumeNameExists = errors.New("volume name already exists on this node")
)
// HostVolumeStateManager manages the lifecycle of volumes in client state.
type HostVolumeStateManager interface {
PutDynamicHostVolume(*cstructs.HostVolumeState) error
GetDynamicHostVolumes() ([]*cstructs.HostVolumeState, error)
DeleteDynamicHostVolume(string) error
}
// Config is used to configure a HostVolumeManager.
type Config struct {
// PluginDir is where external plugins may be found.
PluginDir string
// VolumesDir is where plugins should place the directory
// that will later become a volume's HostPath
VolumesDir string
View on GitHub (pinned to 482b49bf1a)
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
Example fix
// before
name := "shared-volume" // concurrent creates collide
// after
name := fmt.Sprintf("shared-volume-%s", uuid.Generate()) // or reuse existing volume Defensive patterns
Strategy: retry
Validate before calling
// before creating, check the name isn't already claimed
if _, err := state.GetDynamicHostVolume(name); err == nil {
return nil // already exists, reuse
} Try / catch
created, err := lock(name, id)
if errors.Is(err, ErrVolumeNameExists) {
// pick a new unique name or reuse existing volume, then retry
return retryWithNewName()
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- ErrPluginNotExecutable
- ErrAllocBroadcasterClosed
- error creating directory: %w
- error setting directory permission mode: %w
- unknown mkdir parameter: %q
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6210115c92ce701b.
Report an issue: GitHub.