hashicorp/nomad · error

host volume validation error: %v

Error message

host volume validation error: %v

What it means

prepareHostVolumes (Prestart hook) always re-validates requested host volumes against the node's current HostVolumes, so volumes can't be used if the client lost its volume configuration on restart. On validation failure it logs the requested vs existing sets and wraps the multierror as "host volume validation error: %v".

Source

Thrown at client/allocrunner/taskrunner/volume_hook.go:130

		txs, ok := result[req.Type]
		if !ok {
			txs = make(map[string]*structs.VolumeRequest)
			result[req.Type] = txs
		}
		txs[name] = req
	}

	return result
}

func (h *volumeHook) prepareHostVolumes(req *interfaces.TaskPrestartRequest, volumes map[string]*structs.VolumeRequest) ([]*drivers.MountConfig, error) {
	hostVolumes := h.runner.clientConfig.Node.HostVolumes

	// Always validate volumes to ensure that we do not allow volumes to be used
	// if a host is restarted and loses the host volume configuration.
	if err := validateHostVolumes(volumes, hostVolumes, req.Alloc.Name); err != nil {
		h.logger.Error("Requested Host Volume does not exist", "existing", hostVolumes, "requested", volumes)
		return nil, fmt.Errorf("host volume validation error: %v", err)
	}

	hostVolumeMounts, err := h.hostVolumeMountConfigurations(req.Task.VolumeMounts, volumes, hostVolumes, req.Alloc.Name)
	if err != nil {
		h.logger.Error("Failed to generate host volume mounts", "error", err)
		return nil, err
	}

	if len(hostVolumeMounts) > 0 {
		caps, err := h.runner.DriverCapabilities()
		if err != nil {
			return nil, fmt.Errorf("could not validate task driver capabilities: %v", err)
		}
		if caps.MountConfigs == drivers.MountConfigSupportNone {
			return nil, fmt.Errorf(
				"task driver %q for %q does not support host volumes",
				h.runner.task.Driver, h.runner.task.Name)
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Re-add the missing host_volume stanza to the client config and restart the agent
  2. Correct the volume source names in the job spec (nomad job validate)
  3. Constrain the job to nodes that have the volume configured
  4. Check the agent log line "Requested Host Volume does not exist" to see the exact requested vs existing volumes

Example fix

// before (job)
volume_mount {
  volume      = "shareddata"
  destination = "/data"
}
// after (matches client host_volume name)
volume_mount {
  volume      = "shared-data"
  destination = "/data"
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-submit check (pseudocode mirroring the hook)
for _, vm := range task.VolumeMounts {
    if _, ok := node.HostVolumes[vm.Source]; !ok {
        return fmt.Errorf("volume %q not configured on node %s", vm.Source, node.ID)
    }
}

Try / catch

if err := prepareHostVolumes(req); err != nil {
    if strings.HasPrefix(err.Error(), "host volume validation error") {
        // node lost volume config; reschedule on a node that has it
        return rescheduleWithVolumeConstraint(req)
    }
    return err
}

Prevention

When it happens

Trigger: During Prestart, validateHostVolumes returns a multierror of "missing <volume>" entries — i.e., one or more volume_mount sources requested by the task are not in h.runner.clientConfig.Node.HostVolumes.

Common situations: Client host_volume stanza removed from config before agent restart; job rescheduled onto a node without the volume; typo in volume source name; per_alloc allocations where the suffixed volume wasn't configured.

Related errors


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