docker/cli · error
invalid image reference for service
Error message
invalid image reference for service %s: %w
What it means
Raised by loadComposeFile when a service has an image value that fails reference.ParseAnyReference, meaning the image string is not a valid OCI/Docker reference (illegal characters, malformed digest/tag, uppercase in domain handling, etc.). The wrapped %w carries the reference parser error.
Solutions
- Read the wrapped parser error for the precise malformation.
- Correct the image string to the form [registry/]repo[:tag][@digest].
- Strip stray whitespace/quotes introduced by templating or env vars.
- Validate the reference with `docker pull <image>` before deploying.
Example fix
# before
services:
web:
image: myrepo/web: latest # stray space
# after
services:
web:
image: myrepo/web:latest Defensive patterns
Strategy: validation
Validate before calling
// Validate each service image reference before deploy
for _, svc := range config.Services {
if _, err := reference.ParseAnyReference(svc.Image); err != nil {
return fmt.Errorf("service %s invalid image %q: %w", svc.Name, svc.Image, err)
}
} Type guard
// Narrow: type that guarantees a parsed reference
type ValidImage struct{ ref reference.AnyReference }
func NewValidImage(s string) (ValidImage, error) {
r, err := reference.ParseAnyReference(s)
if err != nil {
return ValidImage{}, err
}
return ValidImage{ref: r}, nil
} Prevention
- Strip whitespace and stray quotes from templated image values.
- Validate references with reference.ParseAnyReference in tests.
- Cross-check by `docker pull <image>` before deploy.
When it happens
Trigger: A compose service with `image:` set to a malformed string (e.g. contains spaces, illegal characters, malformed digest, or empty repo). ParseAnyReference at loader.go:59 rejects it and the error wraps the parser detail.
Common situations: Typos in image tags; embedding a digest incorrectly (`image: foo@sha256:not-hex`); trailing whitespace from templating; uppercase letters where lowercase is required; using a bare digest without repo prefix.
Related errors
- invalid image reference for service
- specify a Compose file (with --compose-file)
- compose file contains unsupported options
- unexpected environment variable
- invalid stack name
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/fa24a2fe84be4189.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/stack/loader.go:60
unsupportedProperties := loader.GetUnsupportedProperties(dicts...)
if len(unsupportedProperties) > 0 {
_, _ = fmt.Fprintf(streams.Err(), "Ignoring unsupported options: %s\n\n",
strings.Join(unsupportedProperties, ", "))
}
deprecatedProperties := loader.GetDeprecatedProperties(dicts...)
if len(deprecatedProperties) > 0 {
_, _ = fmt.Fprintf(streams.Err(), "Ignoring deprecated options:\n\n%s\n\n",
propertyWarnings(deprecatedProperties))
}
// Validate if each service has a valid image-reference.
for _, svc := range config.Services {
if svc.Image == "" {
return nil, fmt.Errorf("invalid image reference for service %s: no image specified", svc.Name)
}
if _, err := reference.ParseAnyReference(svc.Image); err != nil {
return nil, fmt.Errorf("invalid image reference for service %s: %w", svc.Name, err)
}
}
return config, nil
}
func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]any {
dicts := make([]map[string]any, 0, len(configFiles))
for _, configFile := range configFiles {
dicts = append(dicts, configFile.Config)
}
return dicts
}
func propertyWarnings(properties map[string]string) string {
msgs := make([]string, 0, len(properties))
for name, description := range properties {View on GitHub (pinned to 4f84911bfe)