docker/cli · error
invalid image source, source cannot be empty
Error message
invalid image source, source cannot be empty
What it means
Returned by handleImageToMount (volume.go:97-98) when a Compose service volume is type: image but has an empty 'source'. An image mount must name the image to mount from (the source field), so an empty source is rejected before the engine call. This mirrors the same pattern used for bind/npipe/cluster mounts requiring a non-empty source.
Solutions
- Add a 'source' field naming the image, e.g. source: myimg:latest.
- Switch to long-form and set type: image plus source explicitly.
- Validate with 'docker compose config'.
Example fix
# before
volumes:
- type: image
target: /app
# after
volumes:
- type: image
source: myrepo/myimg:latest
target: /app Defensive patterns
Strategy: validation
Validate before calling
// Ensure an image-type mount has a non-empty source.
func validateImageMount(v composetypes.ServiceVolumeConfig) error {
if v.Type == "image" && v.Source == "" {
return errors.New("image mount requires a non-empty source (the image reference)")
}
return nil
} Type guard
// imageMountHasSource reports whether an image-type mount names its source image.
func imageMountHasSource(v composetypes.ServiceVolumeConfig) bool {
if v.Type != "image" {
return true
}
return strings.TrimSpace(v.Source) != ""
} Prevention
- Always provide 'source' (an image ref) for type: image mounts.
- Prefer long-form volume entries when using non-volume types to avoid short-syntax defaults.
- Validate compose files with 'docker compose config'.
When it happens
Trigger: In docker-compose.yml: { type: image, target: /app } with no source, or { type: image, source: "", target: /app }. The check at line 97 sees volume.Source == "" and returns the error.
Common situations: Using the short syntax '- /app' (which defaults to volume type) but intending an image mount. Forgetting the image reference when converting from a Dockerfile ref. Templating that emits an empty source.
Related errors
- volume options are incompatible with type image
- bind options are incompatible with type image
- tmpfs options are incompatible with type image
- images options are incompatible with type volume
- tmpfs options are incompatible with type volume
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/eaf88cfd31529b6f.
Report an issue: GitHub.
Appendix: source
Thrown at cli/compose/convert/volume.go:98
return result, nil
}
result.VolumeOptions.Labels = addStackLabel(namespace, stackVolume.Labels)
if stackVolume.Driver != "" || stackVolume.DriverOpts != nil {
result.VolumeOptions.DriverConfig = &mount.Driver{
Name: stackVolume.Driver,
Options: stackVolume.DriverOpts,
}
}
return result, nil
}
func handleImageToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {
result := createMountFromVolume(volume)
if volume.Source == "" {
return mount.Mount{}, errors.New("invalid image source, source cannot be empty")
}
if volume.Volume != nil {
return mount.Mount{}, errors.New("volume options are incompatible with type image")
}
if volume.Bind != nil {
return mount.Mount{}, errors.New("bind options are incompatible with type image")
}
if volume.Tmpfs != nil {
return mount.Mount{}, errors.New("tmpfs options are incompatible with type image")
}
if volume.Cluster != nil {
return mount.Mount{}, errors.New("cluster options are incompatible with type image")
}
if volume.Image != nil {
result.ImageOptions = &mount.ImageOptions{
Subpath: volume.Image.Subpath,
}
}View on GitHub (pinned to 4f84911bfe)