KhueApps
Home/DevOps/Fix Docker "invalid reference format" errors fast

Fix Docker "invalid reference format" errors fast

Last updated: October 06, 2025

Overview

“Error response from daemon: invalid reference format” means Docker parsed an image reference (repository[:tag] or @digest) that does not match the required syntax. This appears in commands like docker run, pull, build -t, tag, push, and even in Dockerfiles (FROM lines) or Compose files.

This guide shows practical, fast fixes.

Quickstart: Fix it fast

  1. Remove protocols and whitespace
  • Wrong: docker pull https://gcr.io/myproj/app:1.0
  • Right: docker pull gcr.io/myproj/app:1.0
  • Trim stray spaces and quotes around image names.
  1. Use valid name syntax
  • Repositories: lowercase only, [a-z0-9_.-], slash-separated.
  • Tags: up to 128 chars, [A-Za-z0-9_.-].
  • Don’t mix tag and digest together.
  1. Keep -t and build context separate
  • Right: docker build -t myorg/app:1.0 .
  • Wrong: docker build -t myorg/app:1.0.
  1. Check env vars
  • Ensure $IMAGE is set and non-empty. Provide defaults: ${IMAGE:-alpine:3.20}.
  1. For Dockerfiles/Compose
  • Dockerfile FROM must resolve to a valid image.
  • Compose image: must be a valid reference without protocols.

Minimal working example

A minimal, correct build and run to compare against your command.

Dockerfile:

FROM alpine:3.20
CMD ["echo", "ok"]

Build and run:

# Build with a valid, lowercase repository and a simple tag
docker build -t myorg/echo:1.0 .

# Run using the exact image:tag reference
docker run --rm myorg/echo:1.0
# output: ok

If the above works on your machine, your Docker setup is fine; your failing command likely has a malformed image reference.

Valid image reference syntax

  • Full form: [registryhost[:port]/]repo[/subrepo][:tag] or [registryhost[:port]/]repo[/subrepo]@sha256:<digest>
  • repo and subrepos: lowercase only; allowed chars: a–z, 0–9, ., _, -
  • tag (optional): 1–128 chars; allowed: A–Z, a–z, 0–9, ., _, -
  • digest (optional): sha256:<64-hex>; cannot be combined with :tag

Examples:

  • Valid: nginx, nginx:1.27.0, myregistry:5000/team/app:2025-10-06, gcr.io/proj/svc@sha256:...
  • Invalid: Nginx:latest (uppercase repo), https://gcr.io/app (protocol), repo/image:tag:extra (extra colon), image:@sha256:... (empty tag before @)

Common causes and fixes

SymptomBadWhyFix
Protocol in imagedocker pull https://gcr.io/proj/app:1Protocol not alloweddocker pull gcr.io/proj/app:1
Uppercase repodocker run MyOrg/App:1Repo must be lowercasedocker run myorg/app:1
Extra colon in tagrepo/app:1:2Multiple tag separatorsrepo/app:1-2 or repo/app:1
Tag + digest togetherapp:1@sha256:abc...Spec forbids bothapp@sha256:abc... or app:1
Trailing space/quotedocker pull "nginx:latest "Space makes tag invaliddocker pull nginx:latest
Missing space before contextdocker build -t app:1.0.CLI treats “1.0.” as tagdocker build -t app:1.0 .
Empty env vardocker run "$IMAGE"IMAGE expands to emptydocker run "${IMAGE:-alpine:3.20}"
Compose with protocolimage: https://index.docker.io/nginxInvalid referenceimage: nginx:latest
Dockerfile FROM undefined ARGFROM ${BASE_IMAGE}BASE_IMAGE empty at build timeARG BASE_IMAGE=alpine:3.20 then FROM ${BASE_IMAGE}

Step-by-step diagnosis

  1. Identify exactly which reference failed
  • Re-run with -D for Docker CLI debug: DOCKER_CLI_HINTS=false docker -D run ...
  • If using Compose: docker compose config to see resolved image values.
  1. Echo your variables
  • Print: echo "IMAGE='$IMAGE'"; ensure not empty, no newline/spaces.
  • Bash default: IMAGE="${IMAGE:-myorg/app:1.0}".
  1. Validate with a quick regex (approximation)
ref='gcr.io/team/app:1.0'
[[ $ref =~ ^([a-z0-9]+([._-][a-z0-9]+)*(:[0-9]+)?/)?([a-z0-9]+([._-][a-z0-9]+)*/)*[a-z0-9]+([._-][a-z0-9]+)*(:([-A-Za-z0-9._]+))?$|^([a-z0-9]+([._-][a-z0-9]+)*(:[0-9]+)?/)?([a-z0-9]+([._-][a-z0-9]+)*/)*[a-z0-9]+([._-][a-z0-9]+)*@sha256:[0-9a-f]{64}$ ]] && echo OK || echo BAD
  1. Test locally without network
  • docker image inspect <ref> 1>/dev/null 2>&1 || echo "Not local yet, but format may still be OK"
  • If inspect fails with “invalid reference format”, your string is malformed.
  1. Common command fixes
  • build: docker build -t myorg/app:1.0 .
  • run: docker run --rm myregistry:5000/myorg/app:1.0
  • pull: docker pull registry.local:5000/team/app:2025.10.06
  • tag: docker tag app@sha256:... registry.local:5000/app:stable

Dockerfile and Compose specifics

  • Dockerfile FROM

    • If using ARG: add a default and pass when building.
    ARG BASE_IMAGE=alpine:3.20
    FROM ${BASE_IMAGE}
    
    • Build: docker build --build-arg BASE_IMAGE=alpine:3.20 -t my/app:1 .
  • docker-compose.yml

    services:
      web:
        image: nginx:1.27.0
    
    • With env default: image: ${IMAGE:-nginx:1.27.0}
    • Avoid protocols and trailing spaces in the image value.

Pitfalls to avoid

  • Mixing port mappings and image names without a space: always separate flags from the image argument.
  • Copy-pasting registry URLs with https:// or trailing slashes.
  • Using uppercase letters in repository components.
  • Accidentally appending the build context dot to the tag (…:tag.).
  • Combining :tag with @sha256:digest.
  • Hidden characters from editors (non-breaking spaces, newlines). Run: printf '%q\n' "$IMAGE".

Performance notes

  • Format errors are caught client-side; fixing the string avoids unnecessary network calls.
  • Validate references before loops or CI matrix runs to save pull time.
  • Prefer immutable digests (app@sha256:...) in CI for reproducible, cache-friendly builds; just don’t pair them with tags.
  • Use local inspect to short-circuit: docker image inspect <ref> is fast and avoids registry hits if the image exists locally.

FAQ

  • What does “invalid reference format” actually mean?

    • The image name/tag/digest string does not match Docker’s expected grammar.
  • Can repository names contain uppercase letters?

    • No. Keep repository and path components lowercase. Tags may include uppercase, but lowercase is safest.
  • Can I include a protocol like https:// in the image?

    • No. Use registryhost[:port]/repo[:tag] without a scheme.
  • Why do I see this in a Dockerfile FROM line?

    • The expanded value (often from ARG) produced an invalid or empty image reference.
  • How do I safely use env vars for images?

    • Provide defaults and trim whitespace: IMAGE="${IMAGE:-alpine:3.20}"; then reference "$IMAGE" in commands.

Series: Docker

DevOps