docker/cli · error

version mismatched between two composefiles

Error message

version mismatched between two composefiles : %v and %v

What it means

Returned by Load when multiple compose files passed in configDetails.ConfigFiles declare different `version` keys (loader.go:99-107). Each file's version is computed via schema.Version; the first sets configDetails.Version and any subsequent file with a differing version aborts the merge.

Solutions

  1. Align the `version:` key across all compose files being merged (or remove it to use the latest).
  2. Make the override file match the base file's version exactly.
  3. If versions genuinely differ, pick one version and migrate the other file to it.

Example fix

# before
# base.yml
version: "3.8"
# override.yml
version: "3.7"
# after
# base.yml
version: "3.8"
# override.yml
version: "3.8"
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all compose files agree on the version key before calling loader.Load.
func versionsMatch(files []types.ConfigFile) error {
    var v string
    for _, f := range files {
        fv := schema.Version(f.Config)
        if v == "" { v = fv; continue }
        if fv != v {
            return fmt.Errorf("version mismatched between two composefiles : %v and %v", v, fv)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Passing two (or more) compose files to Load (e.g. `docker compose -f a.yml -f b.yml`) where a.yml says `version: "3.8"` and b.yml says `version: "3.7"` (or omits/changes it). Reached at loader.go:105-106.

Common situations: Overriding files authored against a different compose spec version; mixing a v3 file with a v2 file; a teammate bumped one file's version but not the override; inconsistent version across a split compose setup.

Related errors


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

Appendix: source

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

			TypeCastMapping: interpolateTypeCastMapping,
		},
	}

	for _, op := range opt {
		op(options)
	}

	configs := []*types.Config{}
	var err error

	for _, file := range configDetails.ConfigFiles {
		configDict := file.Config
		version := schema.Version(configDict)
		if configDetails.Version == "" {
			configDetails.Version = version
		}
		if configDetails.Version != version {
			return nil, fmt.Errorf("version mismatched between two composefiles : %v and %v", configDetails.Version, version)
		}

		if err := validateForbidden(configDict); err != nil {
			return nil, err
		}

		if !options.SkipInterpolation {
			configDict, err = interpolateConfig(configDict, *options.Interpolate)
			if err != nil {
				return nil, err
			}
		}

		if !options.SkipValidation {
			if err := schema.Validate(configDict, configDetails.Version); err != nil {
				return nil, err
			}
		}

View on GitHub (pinned to 4f84911bfe)