docker/cli · error

failed to cast to expected type

Error message

failed to cast to expected type: %w

What it means

Returned by recursiveInterpolate after a value was substituted but the path's registered caster failed to convert the resulting string to its target type (interpolation.go:69-71). The TypeCastMapping (e.g. toInt, toFloat, toBoolean) runs on fields like deploy.replicas or healthcheck.retries; a non-numeric/non-boolean interpolated value is rejected.

Solutions

  1. Set the environment variable to a valid value for the field's expected type (integer for replicas/ports, float for max_failure_ratio, yes/no/true/false/on/off for booleans).
  2. Provide a default in the template, e.g. ${REPLICAS:-2}, so an unset/empty var still casts.
  3. Check the unwrapped inner error (strconv.Atoi / ParseFloat / toBoolean) to see which value failed.

Example fix

# before
environment:
  REPLICAS: auto
deploy:
  replicas: ${REPLICAS}
# after
environment:
  REPLICAS: "3"
deploy:
  replicas: ${REPLICAS:-3}
Defensive patterns

Strategy: validation

Validate before calling

// Validate interpolated values against their expected cast before handing the config to the loader.
var intPaths = []string{"deploy.replicas", "healthcheck.retries"}
func assertInt(name, val string) error {
    if _, err := strconv.Atoi(val); err != nil {
        return fmt.Errorf("%s must be an integer, got %q", name, val)
    }
    return nil
}
// if v := os.Getenv("REPLICAS"); v != "" { if err := assertInt("REPLICAS", v); err != nil { return err } }

Prevention

When it happens

Trigger: An interpolated compose value that must be int/float/bool ends up non-convertible after substitution, e.g. deploy.replicas: ${REPLICAS} with REPLICAS=auto, or healthcheck.retries set to a non-numeric env value. The caster error is wrapped at interpolation.go:71.

Common situations: Env var holding a typo or empty/non-numeric string; a variable reused across fields where the value is text; casting a boolean field to something other than yes/no/true/false/on/off.

Related errors


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

Appendix: source

Thrown at cli/compose/interpolation/interpolation.go:71

	}

	return out, nil
}

func recursiveInterpolate(value any, path Path, opts Options) (any, error) {
	switch value := value.(type) {
	case string:
		newValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue))
		if err != nil || newValue == value {
			return value, newPathError(path, err)
		}
		caster, ok := opts.getCasterForPath(path)
		if !ok {
			return newValue, nil
		}
		casted, err := caster(newValue)
		if err != nil {
			return casted, newPathError(path, fmt.Errorf("failed to cast to expected type: %w", err))
		}
		return casted, nil

	case map[string]any:
		out := map[string]any{}
		for key, elem := range value {
			interpolatedElem, err := recursiveInterpolate(elem, path.Next(key), opts)
			if err != nil {
				return nil, err
			}
			out[key] = interpolatedElem
		}
		return out, nil

	case []any:
		out := make([]any, len(value))
		for i, elem := range value {
			interpolatedElem, err := recursiveInterpolate(elem, path.Next(PathMatchList), opts)

View on GitHub (pinned to 4f84911bfe)