hashicorp/nomad · error
Volume Mount (%d) references undefined volume %s
Error message
Volume Mount (%d) references undefined volume %s
What it means
Task.Validate checks every `volume_mount` against the group's declared `volume` stanzas and emits "Volume Mount (%d) references undefined volume %s" when the mounted name is not defined at group level. Volumes must be declared on the group and referenced by name from tasks.
Source
Thrown at nomad/structs/structs.go:8398
// This task is a Connect proxy so it should not have service blocks
if len(t.Services) > 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have a service block"))
}
if t.Leader {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Connect proxy task must not have leader set"))
}
// Ensure the proxy task has a corresponding service entry
serviceErr := ValidateConnectProxyService(t.Kind.Value(), tg.Services)
if serviceErr != nil {
mErr.Errors = append(mErr.Errors, serviceErr)
}
}
// Validation for volumes
for idx, vm := range t.VolumeMounts {
if _, ok := tg.Volumes[vm.Volume]; !ok {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Volume Mount (%d) references undefined volume %s", idx, vm.Volume))
}
if err := vm.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Volume Mount (%d) is invalid: \"%w\"", idx, err))
}
}
// Validate CSI Plugin Config
if t.CSIPluginConfig != nil {
if t.CSIPluginConfig.ID == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig must have a non-empty PluginID"))
}
if !CSIPluginTypeIsValid(t.CSIPluginConfig.Type) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"%s\"", t.CSIPluginConfig.Type))
}
if t.CSIPluginConfig.StagePublishBaseDir != "" && t.CSIPluginConfig.MountDir != "" &&View on GitHub (pinned to 482b49bf1a)
Solutions
- Add a matching `volume` block on the group with the referenced name
- Fix the volume name in the task's volume_mount to match the group declaration
- Run `nomad job validate` to list all undefined volume references
Example fix
// before
group "app" {
task "srv" {
volume_mount {
volume = "data"
destination = "/data"
}
}
}
// after
group "app" {
volume "data" {
type = "host"
source = "data-vol"
}
task "srv" {
volume_mount {
volume = "data"
destination = "/data"
}
}
} Defensive patterns
Strategy: validation
Validate before calling
for _, vm := range task.VolumeMounts {
if _, ok := group.Volumes[vm.Volume]; !ok {
return fmt.Errorf("task %q mounts undefined volume %q", task.Name, vm.Volume)
}
} Type guard
func volumeDefined(g *structs.TaskGroup, name string) bool { _, ok := g.Volumes[name]; return ok } Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "references undefined volume") { /* declare or fix volume name */ }
} Prevention
- Declare group volumes before wiring task mounts
- Keep volume names in shared constants when generating jobs
- Run `nomad job validate` in CI for every spec change
When it happens
Trigger: A task has `volume_mount { volume = "data" }` but the group has no `volume "data"` stanza, or the names differ (typo/case).
Common situations: Renaming a group volume without updating task mounts; moving a task between groups that lack the volume; host_volume/CSI name mismatches after migration to the volume stanza syntax.
Related errors
- Volume Mount (%d) is invalid: "%w"
- volume clone ID cannot be updated
- volume snapshot ID cannot be updated
- volume requested capabilities update was not compatible with
- volume topology request update was not compatible with exist
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d8c6148e641d6bf2.
Report an issue: GitHub.