{"id":"eaf88cfd31529b6f","repo":"docker/cli","slug":"invalid-image-source-source-cannot-be-empty","errorCode":null,"errorMessage":"invalid image source, source cannot be empty","messagePattern":"invalid image source, source cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/compose/convert/volume.go","lineNumber":98,"sourceCode":"\t\treturn result, nil\n\t}\n\n\tresult.VolumeOptions.Labels = addStackLabel(namespace, stackVolume.Labels)\n\tif stackVolume.Driver != \"\" || stackVolume.DriverOpts != nil {\n\t\tresult.VolumeOptions.DriverConfig = &mount.Driver{\n\t\t\tName:    stackVolume.Driver,\n\t\t\tOptions: stackVolume.DriverOpts,\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc handleImageToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {\n\tresult := createMountFromVolume(volume)\n\n\tif volume.Source == \"\" {\n\t\treturn mount.Mount{}, errors.New(\"invalid image source, source cannot be empty\")\n\t}\n\tif volume.Volume != nil {\n\t\treturn mount.Mount{}, errors.New(\"volume options are incompatible with type image\")\n\t}\n\tif volume.Bind != nil {\n\t\treturn mount.Mount{}, errors.New(\"bind options are incompatible with type image\")\n\t}\n\tif volume.Tmpfs != nil {\n\t\treturn mount.Mount{}, errors.New(\"tmpfs options are incompatible with type image\")\n\t}\n\tif volume.Cluster != nil {\n\t\treturn mount.Mount{}, errors.New(\"cluster options are incompatible with type image\")\n\t}\n\tif volume.Image != nil {\n\t\tresult.ImageOptions = &mount.ImageOptions{\n\t\t\tSubpath: volume.Image.Subpath,\n\t\t}\n\t}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/compose/convert/volume.go#L80-L116","documentation":"Raised at the top of handleImageToMount when a mount of type 'image' has an empty source. For image mounts the source must name the container image to mount, so unlike anonymous volumes there is no sensible default and the converter rejects the entry immediately.","triggerScenarios":"'docker stack deploy' with a service volume entry of type: image whose source key is missing, empty, or resolves to an empty string after variable substitution.","commonSituations":"Forgetting the source: line when trying the newer image-mount feature; an unset environment variable like source: ${IMAGE_REF} expanding to empty; confusing image mounts with anonymous volumes, which do allow empty source.","solutions":["Add a source with the image reference, e.g. source: alpine:latest.","If the source uses variable substitution, ensure the variable is set in the deploy environment ('docker compose config' shows the resolved value).","If you wanted an anonymous volume instead, change type to volume."],"exampleFix":"# before\nvolumes:\n  - type: image\n    target: /mnt/img\n# after\nvolumes:\n  - type: image\n    source: alpine:latest\n    target: /mnt/img","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["docker","compose","image-mount","config-validation","swarm"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}