docker: invalid reference format happens when an image name, tag, or build argument contains whitespace, invalid characters, or empty variable expansion. The most common cause per Stack Overflow and OneUptime: a build arg expands to empty, leaving the image name with a trailing colon or whitespace. The fix: validate the variable before use, quote the args, or use a default value.
Table of contents
- The error in context
- Cause 1: empty env var expansion
- Cause 2: whitespace in arguments
- Cause 3: invalid characters
- Cause 4: registry without component
- Cause 5: trailing/leading colons
- Cause 6: GitLab CI variable expansion
- FAQ
The error in context
Typical error:
docker: invalid reference format: repository name must be lowercase
Or:
docker build -t myapp: . # trailing colon, no tag
Sending build context to Docker daemon
invalid reference format
The team that sees this knows the image name parser rejected the input. The team that doesn’t usually misreads it as a build error.
Cause 1: empty env var expansion
Most common:
# If VERSION is unset or empty:
docker build -t myapp:$VERSION .
# becomes: docker build -t myapp: . (invalid)
Fix:
# Provide a default
VERSION=${VERSION:-latest} docker build -t myapp:$VERSION .
# Or validate before
test -n "$VERSION" || { echo "VERSION required"; exit 1; }
The team that uses shell parameter expansion ${VAR:-default} has fewer of these. The team that assumes the var is set gets this error.
Cause 2: whitespace in arguments
Whitespace in arguments breaks the parser:
# If IMAGE_NAME has a space:
docker tag myapp $IMAGE_NAME:latest
# becomes: docker tag myapp my app:latest (3 args)
Fix: quote the variable.
docker tag myapp "$IMAGE_NAME:latest"
The team that quotes always works. The team that uses unquoted vars with spaces gets invalid reference format plus other weird errors.
Cause 3: invalid characters
Docker image names must match [a-z0-9]+(?:[._-][a-z0-9]+)* (lowercase, numbers, periods, underscores, hyphens). Anything else is invalid:
# Capital letters
docker build -t MyApp . # invalid
# Spaces
docker build -t "my app" . # invalid
# Slashes (other than registry separator)
docker build -t my/app . # valid (registry separator)
docker build -t my//app . # invalid (double slash)
Fix: lowercase the name, remove invalid chars.
Cause 4: registry without component
# Tag without registry
docker tag myapp registry.example.com/team/myapp:v1 # valid
docker tag myapp /team/myapp:v1 # invalid (empty registry)
The team that has the registry URL as a variable validates it’s set before passing to docker tag.
Cause 5: trailing/leading colons
Image names with dangling colons:
docker tag myapp :latest # leading colon
docker tag myapp myapp: # trailing colon, no tag
Both fail. The fix: no leading or trailing colons in the tag position.
Cause 6: GitLab CI variable expansion
GitLab CI’s docker build step had a regression where CI variables expanded to empty strings, causing invalid reference format. The fix per GitLab forum: explicitly handle empty CI vars with defaults, or upgrade GitLab Runner.
FAQ
What does ‘invalid reference format’ mean in plain English?
Docker’s image name parser saw something it couldn’t parse. The team that fixes this by validating inputs avoids it entirely.
Is the error from docker build or docker run?
Either. The parser runs on any command that takes an image name. The team that traces the failing command checks the args being passed.
Why does this happen in CI but not locally?
CI variables are usually different from local - the team that uses os.environ.get('VAR', 'default') style or shell defaults has the issue even locally when the var isn’t set.
Can I use Docker buildx without this error?
Same parser, same rules. Buildx doesn’t add leniency. The team that uses buildx has the same validation needs.
What’s the difference between ‘invalid reference format’ and ‘invalid tag format’?
Both come from the image name parser. ‘Invalid reference format’ is the general error. ‘Invalid tag format’ specifies which component failed. The fix path is the same - validate the image name.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: