docker/compose · error
volume with type=image require Docker Engine %s or later
Error message
volume with type=image require Docker Engine %s or later
What it means
Thrown when a service volume uses the newer 'type: image' mount (mount an image as a volume) but the connected Docker Engine negotiates an API version below 1.48 (Docker Engine < v28). The daemon validates image mounts against the API version negotiated from the request path, so compose pre-checks s.RuntimeAPIVersion(ctx) and refuses early with a clear message instead of an opaque daemon error.
Source
Thrown at pkg/compose/create.go:986
case mount.TypeVolume:
v := findVolumeByTarget(service.Volumes, m.Target)
vol := findVolumeByName(p.Volumes, m.Source)
if v != nil && vol != nil {
// Prefer the bind API if no advanced option is used, to preserve backward compatibility
if !volumeRequiresMountAPI(v.Volume) {
binds = append(binds, toBindString(vol.Name, v))
continue
}
}
case mount.TypeImage:
// The daemon validates image mounts against the negotiated API version
// from the request path, not the server's own max version.
version, err := s.RuntimeAPIVersion(ctx)
if err != nil {
return nil, nil, err
}
if versions.LessThan(version, apiVersion148) {
return nil, nil, fmt.Errorf("volume with type=image require Docker Engine %s or later", dockerEngineV28)
}
}
mounts = append(mounts, m)
}
return binds, mounts, nil
}
func toBindString(name string, v *types.ServiceVolumeConfig) string {
access := "rw"
if v.ReadOnly {
access = "ro"
}
options := []string{access}
if v.Bind != nil && v.Bind.SELinux != "" {
options = append(options, v.Bind.SELinux)
}
if v.Bind != nil && v.Bind.Propagation != "" {
options = append(options, v.Bind.Propagation)View on GitHub (pinned to ddc4b044b6)
Solutions
- Upgrade Docker Engine to v28 or later (API 1.48+) and reconnect
- Verify the negotiated version: docker version --format '{{.Server.APIVersion}}'
- If upgrade is impossible, replace the image volume with a named volume plus an init step that copies content from the image
- Pin tooling that uses type: image to hosts with engine >= 28
Example fix
# before
volumes:
- type: image
source: alpine:latest
target: /mnt/alpine
# after (engine < 28)
volumes:
- mydata:/mnt/data
# plus: docker run --rm -v mydata:/t alpine sh -c 'cp -r /etc /t' Defensive patterns
Strategy: validation
Validate before calling
// Go: check negotiated API version before relying on image volumes
ver, err := cli.ServerAPIVersion(ctx)
if err != nil { return err }
if versions.LessThan(ver, "1.48") {
return fmt.Errorf("type=image volumes need Engine >= 28 (API 1.48), got %s", ver)
} Prevention
- Pin CI/engine images to docker:28+ or newer
- Feature-detect API version in tooling that reads compose files
- Document engine requirements alongside compose files that use type: image
When it happens
Trigger: A compose file with a volume entry whose type is 'image' (e.g. {type: image, source: alpine, target: /data}) run against an engine older than 28.0 (API < 1.48), e.g. Docker 27.x, older Docker Desktop, or an outdated remote DOCKER_HOST.
Common situations: Upgrading compose CLI but not the engine; CI runners pinned to an old docker engine; remote docker context pointing at an old host; feature was added in Engine 28 so older environments silently lack it.
Related errors
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/c3b9a117a2e19240.
Report an issue: GitHub.