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

  1. Retry with a distinct volume name or let the scheduler generate a unique name
  2. Check whether an existing dynamic host volume with that name already satisfies the request and reuse it
  3. Serialize creation through one request path instead of concurrent duplicate calls
  4. 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

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


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