hashicorp/nomad · error
CSIPluginConfig StagePublishBaseDir must not be a subdirecto
Error message
CSIPluginConfig StagePublishBaseDir must not be a subdirectory of MountDir, got: StagePublishBaseDir="%s" MountDir="%s"
What it means
Task.Validate rejects a csi_plugin config whose stage_publish_base_dir lies inside mount_dir (helper.IsSubdirectory check). Nesting staging/publishing scratch space inside the mounted plugin dir can cause mount recursion and corrupted paths, so Nomad forbids it.
Source
Thrown at nomad/structs/structs.go:8418
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 != "" &&
helper.IsSubdirectory(t.CSIPluginConfig.MountDir, t.CSIPluginConfig.StagePublishBaseDir) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig StagePublishBaseDir must not be a subdirectory of MountDir, got: StagePublishBaseDir=\"%s\" MountDir=\"%s\"", t.CSIPluginConfig.StagePublishBaseDir, t.CSIPluginConfig.MountDir))
}
// TODO: Investigate validation of the PluginMountDir. Not much we can do apart from check IsAbs until after we understand its execution environment though :(
}
// Validate default Identity
if t.Identity != nil {
if err := t.Identity.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Identity %q is invalid: %w", t.Identity.Name, err))
}
}
// Validate Identities
for _, wid := range t.Identities {
// Task.Canonicalize should move the default identity out of the Identities
// slice, so if one is found that means it is a duplicate.
if wid.Name == WorkloadIdentityDefaultName {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Duplicate default identities found"))View on GitHub (pinned to 482b49bf1a)
Solutions
- Move stage_publish_base_dir outside mount_dir (e.g. /var/nomad/staging vs /var/nomad/plugin)
- If both were accidentally the same tree, set stage_publish_base_dir to a sibling directory
- Leave stage_publish_base_dir empty to use the client's default staging location
Example fix
// before
csi_plugin {
id = "aws-efs0"
type = "node"
mount_dir = "/var/nomad/plugins"
stage_publish_base_dir = "/var/nomad/plugins/staging"
}
// after
csi_plugin {
id = "aws-efs0"
type = "node"
mount_dir = "/var/nomad/plugins"
stage_publish_base_dir = "/var/nomad/csi-staging"
} Defensive patterns
Strategy: validation
Validate before calling
if cfg != nil && cfg.MountDir != "" && cfg.StagePublishBaseDir != "" {
if rel, _ := filepath.Rel(cfg.MountDir, cfg.StagePublishBaseDir); rel != ".." && !strings.HasPrefix(rel, "..") && rel != "." {
return errors.New("stage_publish_base_dir must not be inside mount_dir")
}
} Prevention
- Keep staging/publish dirs as siblings of the plugin mount dir, never nested
- Pick distinct top-level paths like /var/nomad/plugins and /var/nomad/csi-staging
- Document node client csi_plugin paths in infrastructure config review checklists
When it happens
Trigger: csi_plugin block where both mount_dir and stage_publish_base_dir are set and stage_publish_base_dir is a subdirectory of (or equal to) mount_dir, e.g. mount_dir=/var/nomad/plugin and stage_publish_base_dir=/var/nomad/plugin/staging.
Common situations: Operators configuring node plugin csi_plugin blocks on the client pick a staging dir under the plugin mount dir for tidiness; copy-paste of the same base path into both fields.
Related errors
- missing secret ID
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: VolumeID is required
- CSI.ControllerDetachVolume: ClientCSINodeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/35216ced844d3ca6.
Report an issue: GitHub.