{"record":{"id":"c95bd2feb599da39","repo":"hashicorp/nomad","slug":"invalid-docker-volume-q-v","errorCode":null,"errorMessage":"invalid docker volume %q: %v","messagePattern":"invalid docker volume %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/docker/driver.go","lineNumber":794,"sourceCode":"\tbinds := []string{allocDirBind, taskLocalBind, secretDirBind}\n\n\tlogsROFlag := \"ro\"\n\tif selinuxLabel != \"\" {\n\t\t// Apply SELinux Label to each built-in bind\n\t\tfor i := range binds {\n\t\t\tbinds[i] = fmt.Sprintf(\"%s:%s\", binds[i], selinuxLabel)\n\t\t}\n\t\tlogsROFlag = \"ro,\" + selinuxLabel\n\t}\n\tallocLogsDirBind := fmt.Sprintf(\"%s/logs:%s/logs:%s\", task.TaskDir().SharedAllocDir, task.Env[taskenv.AllocDir], logsROFlag)\n\tbinds = append(binds, allocLogsDirBind)\n\n\tfor _, userbind := range driverConfig.Volumes {\n\t\t// This assumes host OS = docker container OS.\n\t\t// Not true, when we support Linux containers on Windows\n\t\tsrc, dst, mode, err := parseVolumeSpec(userbind, runtime.GOOS)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid docker volume %q: %v\", userbind, err)\n\t\t}\n\n\t\t// Paths inside task dir are always allowed when using the default driver,\n\t\t// Relative paths are always allowed as they mount within a container\n\t\t// When a VolumeDriver is set, we assume we receive a binding in the format\n\t\t// volume-name:container-dest\n\t\t// Otherwise, we assume we receive a relative path binding in the format\n\t\t// relative/to/task:/also/in/container\n\t\tif taskLocalBindVolume {\n\t\t\tsrc = expandPath(task.TaskDir().Dir, src)\n\t\t} else {\n\t\t\t// Resolve dotted path segments\n\t\t\tsrc = filepath.Clean(src)\n\t\t}\n\n\t\tif !d.config.Volumes.Enabled {\n\t\t\tif err := escapingfs.ChildEscapesParentDir(task.AllocDir, src); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"volumes are not enabled; cannot mount host path: %q\", userbind)","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/docker/driver.go#L776-L812","documentation":"containerBinds parses each entry of driverConfig.Volumes with parseVolumeSpec; this error means one of the user-specified volume bind strings is malformed. A valid spec is src:dst[:mode]; parse failures include empty paths, too many/few colon-separated parts, or an invalid mode.","triggerScenarios":"A config.volumes entry fails parseVolumeSpec — e.g. \"only-one-path\", \"src:dst:mode:extra\", empty source/destination, or a mode string that isn't ro/rw/z etc., for the host GOOS.","commonSituations":"Missing destination path (\"/data\" instead of \"/data:/data\"), Windows drive letters colliding with colon splitting, typos like \"host/path:ctr/path:read-only\", or quoting issues in HCL producing wrong strings.","solutions":["Use the full three-part form: \"host-src:container-dest:mode\", at minimum \"src:dst\".","Ensure both src and dst are non-empty absolute or relative paths.","Limit mode to valid values (\"ro\", \"rw\", selinux labels like \"z\", \"Z\").","On Windows, be careful with drive letters (C:\\...) interacting with the spec parser."],"exampleFix":"// before\nconfig { volumes = [\"/data\"] }\n// after\nconfig { volumes = [\"/host/data:/data:rw\"] }","handlingStrategy":"validation","validationCode":"func validBindSpec(spec string) bool {\n\tparts := strings.Split(spec, \":\")\n\tif len(parts) < 2 || len(parts) > 3 { return false }\n\tif parts[0] == \"\" || parts[1] == \"\" { return false }\n\tif len(parts) == 3 {\n\t\tswitch parts[2] { case \"ro\", \"rw\", \"z\", \"Z\", \"\": default: return false }\n\t}\n\treturn true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write volumes as src:dst or src:dst:mode","Double-check specs on Windows where drive letters contain colons","Validate all entries with nomad job validate before submission"],"tags":["docker","volumes","config-parsing"],"backgroundTag":"invalid-volume-spec","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}