docker/cli · error

conflicting parameters "external" and

Error message

conflicting parameters "external" and %q specified for volume %q

What it means

Returned by externalVolumeError from LoadVolumes. A volume marked `external: true` references an existing Docker volume, so it cannot also define `driver`, `driver_opts`, or `labels` (those only apply to volumes Docker would create). The function checks each key in order and reports the first conflicting one.

Solutions

  1. If the volume is truly external, remove `driver`, `driver_opts`, and `labels`.
  2. If you need a driver/labels, set `external: false` (or omit it) so Docker creates the volume.

Example fix

# before
volumes:
  data:
    external: true
    driver: nfs
    driver_opts:
      share: nfs:/exports
# after
volumes:
  data:
    external: true
    name: prod-data
Defensive patterns

Strategy: validation

Validate before calling

func validateExternalVolume(name string, vol map[string]any) error {
    ext, _ := vol["external"]
    if ext != true && (ext == nil || reflect.ValueOf(ext).Kind() != reflect.Map) {
        return nil
    }
    for _, k := range []string{"driver", "driver_opts", "labels"} {
        if _, ok := vol[k]; ok {
            return fmt.Errorf("volume %s: external conflicts with %s", name, k)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: A volume entry has `external: true` together with `driver:`, `driver_opts:`, or `labels:`.

Common situations: Converting a managed volume to external and forgetting to strip the driver/labels; mixing two snippets where one was local and one external.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/0aea3676dcd50318. Report an issue: GitHub.

Appendix: source

Thrown at cli/compose/loader/loader.go:571

			if nw.Name != "" {
				return nil, fmt.Errorf("network %s: network.external.name and network.name conflict; only use network.name", name)
			}
			if versions.GreaterThanOrEqualTo(version, "3.5") {
				logrus.Warnf("network %s: network.external.name is deprecated in favor of network.name", name)
			}
			nw.Name = nw.External.Name
			nw.External.Name = ""
		case nw.Name == "":
			nw.Name = name
		}
		nw.Extras = loadExtras(name, source)
		networks[name] = nw
	}
	return networks, nil
}

func externalVolumeError(volume, key string) error {
	return fmt.Errorf(`conflicting parameters "external" and %q specified for volume %q`, key, volume)
}

// LoadVolumes produces a VolumeConfig map from a compose file Dict
// the source Dict is not validated if directly used. Use Load() to enable validation
func LoadVolumes(source map[string]any, version string) (map[string]types.VolumeConfig, error) {
	volumes := make(map[string]types.VolumeConfig)
	if err := Transform(source, &volumes); err != nil {
		return volumes, err
	}

	for name, volume := range volumes {
		if !volume.External.External {
			continue
		}
		switch {
		case volume.Driver != "":
			return nil, externalVolumeError(name, "driver")
		case len(volume.DriverOpts) > 0:

View on GitHub (pinned to 4f84911bfe)