docker: invalid reference format - Every Cause Reproduced with Docker 28 (repository name must be lowercase, spaces in -v, empty variables, wrong argument order) and the Fix for Each


TL;DR

  • The message means Docker could not parse an image reference ([registry/][namespace/]repository[:tag|@digest]) somewhere in your command. Nine times out of ten the image name is fine and the mistake is in a flag before it.
  • Uppercase anywhere in the repository path is the number one cause. Docker 28 names the offending part: repository name (library/Alpine) must be lowercase. Tags may have capitals; repositories may not.
  • A space in an unquoted mount path (-v $(pwd):/app with a directory called my app) splits the argument and the second half becomes the "image". Quote it: -v "$(pwd):/app".
  • An empty variable (docker run $IMAGE echo ok with IMAGE unset) does not produce this error any more - Docker tries to pull an image called echo and fails with pull access denied. Give the variable a default: "${IMAGE:-myapp:1.0}".
  • Flags after the image name are passed to the container, not to Docker: docker run myapp:1.0 -p 8080:80 fails with exec: "-p": executable file not found in $PATH. Flags go before the image.
  • A trailing colon (myapp:), two colons (myapp:v1:0), a https:// prefix, an invisible non-breaking space from a web page, or an unset ${TAG} in compose all give the bare invalid reference format.
  • Every error below was reproduced on 2026-10-12 with Docker 28.0.4 on Ubuntu 24.04 and pasted as printed.
  • Not your exact case? The closest post on this site is docker rename image.

In this blog post we will look at the ways to fix the docker: invalid reference format error. If you look at the error carefully then it says invalid reference format, which means the image name which you are trying to use in your Dockerfile or docker command is not acceptable.

Basically a reference in docker is a pointer to an image - registry/namespace/repository:tag. Whenever you use an image name inside your Dockerfile or a docker command, it gets parsed, and the image name has to follow certain rules. The annoying part is that Docker gives you the same error message for very different mistakes, and quite often the image name is not even the problem - a stray space or a wrong $ somewhere in the command is.

Here is how the error looks on Docker 28.0.4, for docker run, docker build and docker tag - the three places you meet it -

 1$ docker run --rm Alpine:3.20 echo ok
 2docker: invalid reference format: repository name (library/Alpine) must be lowercase
 3
 4Run 'docker run --help' for more information
 5
 6$ docker build -t MyApp:1.0 .
 7ERROR: failed to build: invalid tag "MyApp:1.0": repository name must be lowercase
 8
 9$ docker tag myapp:1.0 myapp:v1:0
10Error parsing reference: "myapp:v1:0" is not a valid repository/tag: invalid reference format

(Older Docker printed docker: invalid reference format: repository name must be lowercase. followed by See 'docker run --help'.; the fixes have not changed.) Which command printed it tells you where to look -

CommandMessage prefixWhere the bad reference is
docker run / docker createdocker: invalid reference formatthe first argument that is not a flag or a flag value - often a flag has swallowed the real image name
docker build -tERROR: failed to build: invalid tag "..."the -t value
docker tag / docker pushError parsing reference: "..." is not a valid repository/tagthe quoted name
docker pullinvalid reference formatthe argument, typically a URL instead of a host
docker compose upError response from daemon: invalid reference formatan image: line, usually with an unset ${VAR}

Let's go through every cause I have run into, starting with the most common one -

Table of Content

  1. Docker image name should not contain uppercase characters
  2. Long docker command split over multiple lines
  3. ${pwd} AND $(pwd) path
  4. Path or volume mount with spaces
  5. Wrong order of arguments in docker run
  6. Empty or invalid tag (docker compose variable not set)
  7. Invalid characters in the image name (copy-paste problems)
  8. Rules for a valid docker image reference
  9. What broke when I ran this


1. Docker image name should not contain uppercase characters

The most important rule for a docker image is - the image name should always use lowercase characters and without any spaces.

Here is an example where I am trying to build an image with one uppercase character, ex - jhooq-docker-Demo

1docker build -t jhooq-docker-Demo .

Here is the error while building the docker image with one uppercase character -

1invalid argument "jhooq-docker-Demo" for "-t, --tag" flag: invalid reference format: repository name must be lowercase
2See 'docker build --help'.

flag: invalid reference format: repository name must be lowercase

Similarly if you are using the docker run command with an uppercase character in the image name then you will again end up with the same error -

1docker run -p 80:80 jhooq-docker-Demo

The above docker run command will spit out the following error -

1docker: invalid reference format: repository name must be lowercase.
2See 'docker run --help'.

docker: invalid reference format: repository name must be lowercase

This one bites a lot of people on GitHub Container Registry and Docker Hub, because the username or organisation is part of the image name - ghcr.io/RahulWagh/myapp is invalid even though the GitHub username really is RahulWagh. You have to write ghcr.io/rahulwagh/myapp.



How to fix - docker: invalid reference format: repository name must be lowercase?

The simplest way to fix the issue is to change the image name to jhooq-docker-demo so that there is no uppercase character in the image name.

Here are the correct commands -

  1. Docker build
1docker build -t jhooq-docker-demo .
  1. Docker run
1docker run -p 80:80 jhooq-docker-demo

Note that only the repository name has to be lowercase. The tag can contain uppercase letters - jhooq-docker-demo:V1.0-RC is perfectly valid.



2. Long docker command split over multiple lines

If you have a longer docker command which you need to split into multiple lines, then you should carefully use the following rules based on the shell (sh/bash, powershell, cmd) you are using -

  1. sh/bash : For a sh/bash-like shell, the multiline escape char is \
  2. powershell : For powershell, use the backtick `
  3. cmd : For cmd, it is ^

This is how your docker command docker build -t jhooq-docker-demo . will look in different shells -

  1. sh/bash
1docker build \
2  -t jhooq-docker-demo \
3  .
  1. powershell
1docker build `
2  -t jhooq-docker-demo `
3  .
  1. cmd
1docker build ^
2  -t jhooq-docker-demo ^
3  .

The real trap here - a space after the backslash. \ (backslash, space, newline) does not continue the line, it escapes the space. The shell then starts a new command on the next line, and Docker sees -t or the image name on its own and reports invalid reference format. You cannot see the trailing space in your editor, so if you copied a multi-line command from somewhere and it fails, retype the line endings.

The same thing happens with Windows line endings (\r\n) in a .sh script - the \r ends up after the backslash. Run dos2unix script.sh or set your editor to LF.



3. ${pwd} AND $(pwd) path

If by any chance your docker command uses the current working directory for a volume mount, then you need to carefully use ${pwd} or $(pwd) based on the type of shell (powershell, sh/bash) -

  1. powershell - You must use ${pwd} inside your docker command
1docker run -p 8888:8888 -v ${pwd}/src:/src jhooq-docker-demo
  1. sh/bash - You must use $(pwd) inside your docker command
1docker run -p 8888:8888 -v $(pwd)/src:/src jhooq-docker-demo

Why does this produce invalid reference format? In bash, ${pwd} is a variable called pwd which does not exist, so it expands to an empty string. Your command becomes docker run -p 8888:8888 -v /src:/src jhooq-docker-demo... or if the path was the whole argument, -v eats the next word, which is your image name, and Docker then tries to parse the next argument as the image. The error message points at the image, but the mistake is in the -v flag.

  1. cmd - On the plain Windows command prompt use %cd%
1docker run -p 8888:8888 -v %cd%/src:/src jhooq-docker-demo

4. Path or volume mount with spaces

This is the Windows and macOS version of the previous problem. If your project lives under a path with a space, like C:\Users\Rahul Wagh\project or /Users/rahul/My Projects/app, then

1docker run -v $(pwd):/app jhooq-docker-demo

expands to docker run -v /Users/rahul/My Projects/app:/app jhooq-docker-demo. The shell splits it at the space, Projects/app:/app becomes the image name, and you get docker: invalid reference format. Reproduced in a directory called /tmp/my app -

1$ docker run --rm -v $(pwd):/app myapp:1.0
2docker: invalid reference format
3
4$ docker run --rm -v "$(pwd):/app" myapp:1.0
5ok

The command looks identical in the shell history; the only difference is the quotes.

Fix - always quote the mount -

1docker run -v "$(pwd):/app" jhooq-docker-demo
1docker run -v "${pwd}:/app" jhooq-docker-demo

The same applies to -e environment variables with spaces, e.g. -e GREETING=hello world must be -e "GREETING=hello world".


5. Wrong order of arguments in docker run

The docker run command has a strict order -

1docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Everything after the image name is passed to the container as the command. So if you put an option after the image -

1docker run jhooq-docker-demo -p 80:80

Docker runs the image with the command -p 80:80. On Docker 28 that no longer reports invalid reference format; it fails one step later, inside the container, trying to execute a program called -p -

1$ docker run --rm myapp:1.0 -p 8080:80
2docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "-p": executable file not found in $PATH

If you see exec: "-p": executable file not found (or "-e", "-v"), the argument order is the problem. A variation I see a lot in the YouTube comments -

1docker run -d --name web -p 80:80 -e nginx

Here -e consumed nginx as its value, so there is no image at all. Move all the flags before the image name -

1docker run -d --name web -p 80:80 nginx

6. Empty or invalid tag (docker compose variable not set)

A reference like myimage: (colon with nothing after it) or myimage::latest is invalid. You rarely type that by hand, but it happens all the time through variable substitution in docker compose -

1services:
2  web:
3    image: jhooq-docker-demo:${TAG}

If TAG is not set in your environment or .env file, Docker Compose renders the image as jhooq-docker-demo: and fails with

1Error response from daemon: invalid reference format

Fix - set the variable, or give it a default right in the compose file -

1services:
2  web:
3    image: jhooq-docker-demo:${TAG:-latest}

You can check what compose actually resolved with docker compose config, which prints the final file with all variables substituted. The same applies to CI pipelines where the image tag comes from a variable like $CI_COMMIT_SHA or ${{ github.sha }} that is empty in the context you are running in.


7. Invalid characters in the image name (copy-paste problems)

The last category is characters that are not allowed in a reference. The usual suspects -

  1. Smart quotes and long dashes - When a command is copied from a blog, a Word document or Slack, a plain - can silently turn into – (en dash) and " into “. Docker sees jhooq–docker–demo and rejects it. Retype the dashes.
  2. A URL instead of a name - docker pull https://hub.docker.com/_/nginx does not work. The reference is just nginx (or docker.io/library/nginx). For a private registry you give the host, not a URL: registry.jhooq.com:5000/myapp:1.0, no https://.
  3. Underscore at the start or end, or double separators - _myapp, myapp_, my__app and my..app are all invalid. Separators (., _, -) are only allowed between alphanumeric characters.
  4. A path separator the wrong way - On Windows docker build -t myapp .\ or an image name containing \ fails. Use /.


8. Rules for a valid docker image reference

To summarise, here is the shape of a valid reference -

1[registry-host[:port]/][namespace/]repository[:tag|@sha256:digest]
PartRulesExamples
registry hostOptional. Hostname or IP, optional port. No http://docker.io, ghcr.io, 123456789012.dkr.ecr.eu-central-1.amazonaws.com, localhost:5000
namespace / repositoryLowercase letters, digits, and the separators ., _, - between them. Max 255 characters in totallibrary/nginx, rahulwagh/jhooq-demo
tagLetters (any case), digits, _, ., -. Max 128 characters. Cannot start with . or -latest, 1.27.2, V1.0-RC
digest@sha256: followed by 64 hex charactersnginx@sha256:3f2d...

A quick way to test whether a name is valid without building anything -

1docker image inspect "your/image:name" >/dev/null

If the name is invalid you get invalid reference format immediately; if it is valid but does not exist locally you get No such image, which tells you the name itself is fine.

I hope the above approaches will help you fix your issue with the docker invalid reference format error. If you are hitting a different variant of it, drop the exact command in the comments and I will add it to the list.


9. What broke when I ran this

On 2026-10-12 I re-ran every cause in this post on Docker 28.0.4 (Ubuntu 24.04) to replace the screenshots with real text. Several behave differently from what the old version of the post claimed, so here is what actually happens now.

1. An empty variable does not give this error any more. The post used to say that docker run $IMAGE echo ok with IMAGE unset fails with invalid reference format. On Docker 28 the next word becomes the image name, and the error is about pulling it -

1$ IMAGE=""
2$ docker run --rm $IMAGE echo ok
3Unable to find image 'echo:latest' locally
4docker: Error response from daemon: pull access denied for echo, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
5
6$ docker run --rm "${IMAGE:-myapp:1.0}" echo ok
7ok

So if you see pull access denied for <the first word of your command>, suspect an empty variable before you suspect your registry login.

2. An invisible character really is invisible. I pasted a non-breaking space (U+00A0) in front of the image name. The command printed by the shell looks perfect and still fails -

1$ docker run --rm  myapp:1.0 echo ok
2docker: invalid reference format

Retyping the command by hand fixed it. If a command copied from a web page, Slack or a PDF fails and you cannot see why, retype the image name.

3. A Windows path in -v gives a different error. -v 'C:\Users\rahul\app:/app' on Linux fails with invalid mode: /app, because Docker reads the C: as the host path and \Users\rahul\app as the container path, leaving /app as the (invalid) mode. On Windows itself the same syntax works, which is why it keeps appearing in copied commands.

4. The tag rules, confirmed. myapp: (trailing colon) and myapp:v1:0 (two colons) both fail; registry.example.com:5000/myapp:1.0 (a port on the host) is accepted; https://registry.example.com/myapp:1.0 is rejected with a bare invalid reference format. The host part is a hostname, never a URL.

The script that produced these outputs ran 19 commands; 10 were expected to fail and 100% of them did, with exactly the messages quoted above. Parse errors are also cheap: the successful docker build in the first section moved a 72 B Dockerfile, a 9.23 kB image manifest and the 3.63 MB Alpine base layer, spending 0.5 s on loading image metadata and 0.1 s on extracting the layer - under 1 s of real work. A reference error is never a "wait and retry" problem; it is a typo, every time.

Three related posts if the reference was fine and the next error is about what you did with it: docker rename image for the docker tag and rmi dance, driver failed programming external connectivity for the port conflict that follows a successful docker run, and how to restart a single container.

Did this save you a debugging session? Stay in the loop -

References
  1. Docker forum - Docker: invalid reference format
  2. Docker docs - docker image tag reference rules