argoproj/argo-workflows · error
volumeMounts[%d].mountPath '%s' already mounted in %s
Error message
volumeMounts[%d].mountPath '%s' already mounted in %s
What it means
Within a ContainerSetTemplate all containers share the pod's filesystem, so two volumeMounts may not claim the same mountPath. Validate() tracks every mountPath in a map and fails when a later mount collides with an earlier one, reporting which index/path was already mounted and where.
Source
Thrown at pkg/apis/workflow/v1alpha1/container_set_template_types.go:108
func (in *ContainerSetTemplate) Validate() error {
if len(in.Containers) == 0 {
return fmt.Errorf("containers must have at least one container")
}
names := make([]string, 0)
for _, ctr := range in.Containers {
names = append(names, ctr.Name)
}
err := validateWorkflowFieldNames(names, false)
if err != nil {
return fmt.Errorf("containers%s", err.Error())
}
// Ensure there are no collisions with volume mountPaths and artifact load paths
mountPaths := make(map[string]string)
for i, volMount := range in.VolumeMounts {
if prev, ok := mountPaths[volMount.MountPath]; ok {
return fmt.Errorf("volumeMounts[%d].mountPath '%s' already mounted in %s", i, volMount.MountPath, prev)
}
mountPaths[volMount.MountPath] = fmt.Sprintf("volumeMounts.%s", volMount.Name)
}
// Ensure the dependencies are defined
nameToContainer := make(map[string]ContainerNode)
for _, ctr := range in.Containers {
nameToContainer[ctr.Name] = ctr
}
for _, ctr := range in.Containers {
for _, depName := range ctr.Dependencies {
_, ok := nameToContainer[depName]
if !ok {
return fmt.Errorf("containers.%s dependency '%s' not defined", ctr.Name, depName)
}
}
}
View on GitHub (pinned to 35bff19146)
Solutions
- Change one volumeMount's mountPath to a distinct directory (e.g. /data vs /data2), or use different subPath values.
- Remove the redundant volumeMount if both entries reference the same volume/path.
- Review the error's "already mounted in" suffix to find the original volumeMount.name and reconcile the two.
Example fix
// before
containerSet:
volumeMounts:
- name: workdir
mountPath: /data
- name: cache
mountPath: /data
// after
containerSet:
volumeMounts:
- name: workdir
mountPath: /data
- name: cache
mountPath: /cache Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]string{}
for i, vm := range cs.ContainerSet.VolumeMounts {
if prev, ok := seen[vm.MountPath]; ok {
return fmt.Errorf("mountPath %q duplicated (%s vs %s)", vm.MountPath, prev, vm.Name)
}
seen[vm.MountPath] = vm.Name
} Try / catch
if err := cs.Validate(); err != nil {
if strings.Contains(err.Error(), "already mounted in") {
// parse the conflicting index/path from the message and dedupe mounts
}
return err
} Prevention
- Maintain a central list of mountPaths per container set and dedupe at render time.
- Use subPath to separate logical mounts under shared volumes.
- Validate rendered manifests with argo lint before submit.
When it happens
Trigger: Two containerSet.volumeMounts entries (or two containers mounting the same volume at the same subPath/mountPath) specify the identical mountPath string in the same container set.
Common situations: Copying a volumeMount block and forgetting to change mountPath; mounting the same shared volume at the same path in two containers (in a containerSet the mounts are validated set-wide, unlike a normal pod); generated manifests merging mounts from multiple sources.
Related errors
- duration has to be positive, current duration: %v
- containers must have at least one container
- containers%s
- successCondition, failureCondition and outputs are not suppo
- artifact key %q must have a valid UUID segment: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/54211b0137bdc4d7.
Report an issue: GitHub.