{"record":{"id":"8ffa8dbcd413c6d3","repo":"hashicorp/nomad","slug":"host-volume-validation-error-v","errorCode":null,"errorMessage":"host volume validation error: %v","messagePattern":"host volume validation error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/volume_hook.go","lineNumber":130,"sourceCode":"\t\ttxs, ok := result[req.Type]\n\t\tif !ok {\n\t\t\ttxs = make(map[string]*structs.VolumeRequest)\n\t\t\tresult[req.Type] = txs\n\t\t}\n\t\ttxs[name] = req\n\t}\n\n\treturn result\n}\n\nfunc (h *volumeHook) prepareHostVolumes(req *interfaces.TaskPrestartRequest, volumes map[string]*structs.VolumeRequest) ([]*drivers.MountConfig, error) {\n\thostVolumes := h.runner.clientConfig.Node.HostVolumes\n\n\t// Always validate volumes to ensure that we do not allow volumes to be used\n\t// if a host is restarted and loses the host volume configuration.\n\tif err := validateHostVolumes(volumes, hostVolumes, req.Alloc.Name); err != nil {\n\t\th.logger.Error(\"Requested Host Volume does not exist\", \"existing\", hostVolumes, \"requested\", volumes)\n\t\treturn nil, fmt.Errorf(\"host volume validation error: %v\", err)\n\t}\n\n\thostVolumeMounts, err := h.hostVolumeMountConfigurations(req.Task.VolumeMounts, volumes, hostVolumes, req.Alloc.Name)\n\tif err != nil {\n\t\th.logger.Error(\"Failed to generate host volume mounts\", \"error\", err)\n\t\treturn nil, err\n\t}\n\n\tif len(hostVolumeMounts) > 0 {\n\t\tcaps, err := h.runner.DriverCapabilities()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"could not validate task driver capabilities: %v\", err)\n\t\t}\n\t\tif caps.MountConfigs == drivers.MountConfigSupportNone {\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"task driver %q for %q does not support host volumes\",\n\t\t\t\th.runner.task.Driver, h.runner.task.Name)\n\t\t}","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/volume_hook.go#L112-L148","documentation":"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\".","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-add the missing host_volume stanza to the client config and restart the agent","Correct the volume source names in the job spec (nomad job validate)","Constrain the job to nodes that have the volume configured","Check the agent log line \"Requested Host Volume does not exist\" to see the exact requested vs existing volumes"],"exampleFix":"// before (job)\nvolume_mount {\n  volume      = \"shareddata\"\n  destination = \"/data\"\n}\n// after (matches client host_volume name)\nvolume_mount {\n  volume      = \"shared-data\"\n  destination = \"/data\"\n}","handlingStrategy":"validation","validationCode":"// pre-submit check (pseudocode mirroring the hook)\nfor _, vm := range task.VolumeMounts {\n    if _, ok := node.HostVolumes[vm.Source]; !ok {\n        return fmt.Errorf(\"volume %q not configured on node %s\", vm.Source, node.ID)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := prepareHostVolumes(req); err != nil {\n    if strings.HasPrefix(err.Error(), \"host volume validation error\") {\n        // node lost volume config; reschedule on a node that has it\n        return rescheduleWithVolumeConstraint(req)\n    }\n    return err\n}","preventionTips":["Validate jobs in CI so missing volumes are caught before scheduling","Snapshot client host_volume config; alert on diffs after restarts","Add node constraints for jobs requiring specific host volumes","After client restarts, confirm HostVolumes are reloaded before allowing allocations"],"tags":["nomad","volumes","config","host-volume"],"backgroundTag":"missing-host-volume","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}