hashicorp/nomad · error
volume name %q cannot be a reserved word for Windows filenam
Error message
volume name %q cannot be a reserved word for Windows filenames
What it means
When a Windows bind spec's destination looks like a named volume (a bare name, no path separator), the parser checks it against Windows reserved filenames (CON, PRN, AUX, NUL, COM1..9, LPT1..9). A reserved word is an illegal volume name on Windows, so the spec is rejected before any filesystem access.
Source
Thrown at drivers/docker/win32_volume_parse.go:140
split = append(split, destination)
}
}
if mode, exists := matchgroups["mode"]; exists {
if mode != "" {
split = append(split, mode)
}
}
// Fix #26329. If the destination appears to be a file, and the source is null,
// it may be because we've fallen through the possible naming regex and hit a
// situation where the user intention was to map a file into a container through
// a local volume, but this is not supported by the platform.
if matchgroups["source"] == "" && matchgroups["destination"] != "" {
volExp := regexp.MustCompile(`^` + rxName + `$`)
reservedNameExp := regexp.MustCompile(`^` + rxReservedNames + `$`)
if volExp.MatchString(matchgroups["destination"]) {
if reservedNameExp.MatchString(matchgroups["destination"]) {
return nil, fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", matchgroups["destination"])
}
} else {
exists, isDir, _ := currentFileInfoProvider.fileInfo(matchgroups["destination"])
if exists && !isDir {
return nil, fmt.Errorf("file '%s' cannot be mapped. Only directories can be mapped on this platform", matchgroups["destination"])
}
}
}
return split, nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Rename the volume to a non-resident name (e.g. "mydata" instead of "CON").
- If you meant a host path, add separators/drive letter so it isn't treated as a volume name.
- Check against the Windows reserved list: CON, PRN, AUX, NUL, COM1-9, LPT1-9.
Example fix
// before volumes = ["NUL:C:/data"] // after volumes = ["appdata:C:/data"]
Defensive patterns
Strategy: validation
Validate before calling
var reserved = map[string]bool{"CON": true, "PRN": true, "AUX": true, "NUL": true,
"COM1": true, "COM2": true, "COM3": true, "COM4": true, "COM5": true, "COM6": true, "COM7": true, "COM8": true, "COM9": true,
"LPT1": true, "LPT2": true, "LPT3": true, "LPT4": true, "LPT5": true, "LPT6": true, "LPT7": true, "LPT8": true, "LPT9": true}
if reserved[strings.ToUpper(volumeName)] {
return fmt.Errorf("volume name %s is reserved on Windows", volumeName)
} Try / catch
if err := validateVolumeName(name); err != nil {
return fmt.Errorf("rename volume in jobspec: %w", err)
} Prevention
- Use descriptive multi-character names (e.g. appdata) — never DOS device names.
- Add a jobspec linter rule rejecting reserved filenames.
- Case-insensitive comparison: "con" is as invalid as "CON".
When it happens
Trigger: windowsSplitRawSpec with a spec like "CON:C:\dest" or "nul:/data" where the source/destination matches rxName but also rxReservedNames.
Common situations: Volume names chosen carelessly in jobspecs (e.g. testing with "NUL"), or a short token that accidentally equals a reserved device name.
Related errors
- not <src>:<destination> format
- invalid volume specification: '%s'
- file '%s' cannot be mapped. Only directories can be mapped o
- running container as ContainerAdmin is unsafe; change the co
- the image does not exist: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/87863e8be0fdcd77.
Report an issue: GitHub.