Skip to content
Latchkey

Docker "invalid reference format" in CI

Docker rejected an image reference. invalid reference format means the name/tag is malformed - uppercase in the repository part, illegal characters, an empty interpolated variable, or a stray colon/slash.

What this error means

A docker build -t, docker tag, docker push, or docker pull fails immediately with invalid reference format. The reference string is bad before any registry is contacted.

docker
docker: invalid reference format
# e.g. docker build -t MyOrg/API:1.4.2 .   (uppercase not allowed in repo name)
# or an empty var: docker build -t ghcr.io/myorg/api: .

Diagnose it: separate auth from naming from rate limits

Registry errors look alike and have unrelated causes. Work out which of the three you have before changing credentials, because a malformed image reference produces an error that reads like an authentication failure.

Terminal
# 1. is the reference even valid? (lowercase, no spaces, valid tag)
docker image inspect "$IMAGE" 2>&1 | head -2

# 2. are you authenticated to the right registry?
cat ~/.docker/config.json | grep -o '"[^"]*\.[^"]*"' | head

# 3. are you rate limited? (Docker Hub anonymous pulls)
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimit-preview/test:pull" \
  | grep -o '"token"' >/dev/null && echo "token ok"

Common causes

Uppercase or illegal characters in the name

Repository names must be lowercase and use a limited character set. Uppercase letters or illegal characters make the reference invalid.

An empty interpolated variable

A tag built from ${VERSION} where the variable is unset collapses to image: or a missing component, which is malformed.

Stray or doubled separators

An extra colon, a trailing slash, or a double tag produces a reference Docker cannot parse.

How to fix it

Use a lowercase, fully-formed reference

Lowercase the repository and ensure every component is present.

Terminal
docker build -t ghcr.io/myorg/api:1.4.2 .
# lowercase a dynamic name:
docker build -t "ghcr.io/$(echo "$ORG" | tr '[:upper:]' '[:lower:]')/api:1.4.2" .

Default tag variables so they are never empty

Give the tag a fallback so an unset variable does not break the reference.

Terminal
TAG="${VERSION:-latest}"
docker build -t ghcr.io/myorg/api:"$TAG" .

Authenticate in the job, not in the image

.github/workflows/ci.yml
- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

# GHCR needs this on the job or the push is rejected as unauthorised
permissions:
  contents: read
  packages: write

How to prevent it

  • Keep repository names lowercase and within the allowed character set.
  • Default tag variables so an empty value cannot produce image:.
  • Lint computed image references before using them.

Frequently asked questions

What causes Docker "invalid reference format" in CI?
There are 3 common causes: uppercase or illegal characters in the name, an empty interpolated variable, and stray or doubled separators. Repository names must be lowercase and use a limited character set.
How do I fix Docker "invalid reference format" in CI?
There are 2 fixes depending on which cause you have: use a lowercase, fully-formed reference and default tag variables so they are never empty. Work through them in order, since the first is the most common.
What does Docker "invalid reference format" in CI actually mean?
A docker build -t, docker tag, docker push, or docker pull fails immediately with invalid reference format.
How do I stop Docker "invalid reference format" in CI happening again?
Keep repository names lowercase and within the allowed character set. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

This is a registry failure, not a bug in your code. Latchkey detects, repairs, and retries it for you. Start free → 30-day trial · No credit card