Podman Short Names and Registry Resolution
`podman pull hello-world` fetches `quay.io/podman/hello`, not Docker's image - and the same command on the same host returns a different image once one is already in your store. The order is local storage, alias table, search registries, error.
Containers and Images Guide 7 of 47 Beginner
- OSUbuntu 26.04 LTS (resolute)
- Podman5.7.0
- Runtimecrun 1.21
- Networknetavark 1.16.1
- TimeAbout 12 min
- Reviewed22 August 2026
Written against the versions above. Podman follows the distribution here rather than a vendor repository, so the version you get is the one Ubuntu shipped. The commands are stable across 5.x.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| PODMAN01 | 192.168.0.24 | Ubuntu 26.04 LTS | Primary Container Host | 2 Core | 4 GB | 50 GB |
Before you start
- Podman installed - see guide 1.
- Network access to both
docker.ioandquay.io, because the resolution order sends you to each of them.
-
What Ubuntu ships
Two pieces of configuration decide where a bare image name goes, and on a fresh Ubuntu they are in an unexpected state.
/etc/containers/registries.conf.d/containsshortnames.confwith 132 aliases - explicit mappings from a bare name to a fully qualified one. Read three of them:"hello-world" = "quay.io/podman/hello" "alpine" = "docker.io/library/alpine" "busybox" = "docker.io/library/busybox"alpineandbusyboxpoint at Docker Hub.hello-worlddoes not - it points at Podman's own image on quay.io.Meanwhile
unqualified-search-registriesis empty:search=. There is no fallback registry. A name either resolves through that table or not at all.bash Example session ls /etc/containers/registries.conf.d/shortnames.confgrep -cE '^\s*"' /etc/containers/registries.conf.d/shortnames.conf132grep -E '^\s*"(hello-world|alpine|busybox)"' /etc/containers/registries.conf.d/shortnames.conf "hello-world" = "quay.io/podman/hello" "alpine" = "docker.io/library/alpine" "busybox" = "docker.io/library/busybox"podman info --format 'search={{.Registries.search}}'search=<no value>Expected resultOne file, 132 aliases, three mappings, and an empty search list.
Success conditionYou can name the file that decides where a bare image name goes.
-
The alias table sends you to quay.io
Remove both hello images so nothing is cached, then pull the bare name.
Podman tells you exactly what it did:
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf) Trying to pull quay.io/podman/hello:latest...That line is the feature. Podman refuses to silently guess a registry, so when it resolves a name it names the file that told it to.
And note what you now have:
quay.io/podman/hello. If you typedhello-worldexpecting Docker's image, you did not get it. Different image, different registry, different maintainer - and the command looked like it worked, because it did.bash Example session podman rmi -f docker.io/library/hello-world quay.io/podman/hellopodman pull hello-worldResolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf)Trying to pull quay.io/podman/hello:latest...Getting image source signaturesCopying blob sha256:81df7ff16254ed9756e27c8de9ceb02a9568228fccadbf080f41cc5eb5118a44Copying config sha256:5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0Writing manifest to image destination5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0podman images --format 'table {{.Repository}} {{.Tag}}'REPOSITORY TAGdocker.io/library/nginx alpinedocker.io/library/redis alpinedocker.io/library/alpine latestquay.io/podman/hello latestExpected resultA
Resolved ... as an aliasline, a pull from quay.io, andquay.io/podman/helloin your image list.Success conditionYou have the alias table's answer, and it is not Docker Hub.
-
Local storage decides before the alias table does
Now the part that makes this worth a guide rather than a footnote.
Pull the Docker Hub image by its full name, remove the quay one, and run the exact same bare-name pull again:
$ podman pull hello-world Trying to pull docker.io/library/hello-world:latest...No
Resolved ... as an aliasline, and a different registry. The alias table was not consulted, because a local image already matched the name.So the resolution order is:
- Local storage - an image you already have wins outright
- The alias table -
shortnames.conf unqualified-search-registries- empty here- Error
The consequence is the thing to carry away:
podman pull hello-worldis not a reproducible instruction. It depends on what is already in the store, so it can give one image on your laptop and a different one on a fresh CI runner. Write the registry out and this whole ordering stops mattering.bash Example session podman pull docker.io/library/hello-worldTrying to pull docker.io/library/hello-world:latest...Getting image source signaturesCopying blob sha256:4f55086f7dd096d48b0e49be066971a8ed996521c2e190aa21b2435a847198b4Copying config sha256:e2ac70e7319a02c5a477f5825259bd118b94e8b02c279c67afa63adab6d8685bWriting manifest to image destinatione2ac70e7319a02c5a477f5825259bd118b94e8b02c279c67afa63adab6d8685bpodman rmi quay.io/podman/helloUntagged: quay.io/podman/hello:latestDeleted: 5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0podman pull hello-worldResolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf)Trying to pull quay.io/podman/hello:latest...Getting image source signaturesCopying blob sha256:81df7ff16254ed9756e27c8de9ceb02a9568228fccadbf080f41cc5eb5118a44Copying config sha256:5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0Writing manifest to image destination5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0podman images --format 'table {{.Repository}} {{.Tag}}'REPOSITORY TAGdocker.io/library/nginx alpinedocker.io/library/redis alpinedocker.io/library/alpine latestquay.io/podman/hello latestExpected resultThe same command resolving to docker.io this time, with no alias line.
Success conditionYou have produced two different images from one identical command.
-
A name in neither place
traefikis a real, popular image. It is not in the 132 aliases:Error: short-name "traefik" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"Exit 125.
library/busyboxfails identically - note that a slash does not make a name qualified. A name is qualified only when it starts with a registry hostname.This is the failure most people actually hit, and the error is unusually good: it names both mechanisms that could have saved it and the file it looked in. Compare it with a tool that quietly assumes Docker Hub and pulls something you did not ask for.
bash Example session podman pull traefikError: short-name "traefik" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"[exit 125]podman pull library/busyboxError: short-name "library/busybox" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"[exit 125]Expected resultThe short-name error and exit 125, twice.
Success conditionYou can read the error and know which of the two mechanisms to reach for.
-
Add a search registry, and decide whether you want to
One file makes bare names behave the Docker way:
unqualified-search-registries = ["docker.io"]search=[docker.io], andlibrary/busyboxnow pulls.Whether to do this is a real decision rather than a formality. Turning it on buys convenience and pasteable Docker instructions. It costs you the guarantee that an image name means one thing: with a search list, a typo or a name that has since been squatted resolves to whatever that registry serves, and you will not be told which registry was used.
The recommendation for anything shared - a Containerfile, a Compose file, a manifest, a script - is to write the registry out and leave the search list empty. The empty default is not Podman being awkward; it is Podman refusing to guess on your behalf.
bash Example session sudo -n tee /etc/containers/registries.conf.d/99-docker-hub.conf <<'CONF'unqualified-search-registries = ["docker.io"]CONFunqualified-search-registries = ["docker.io"]podman info --format 'search={{.Registries.search}}'search=<no value>podman pull library/busyboxError: short-name "library/busybox" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"[exit 125]Expected result
search=[docker.io], then a successful pull of a previously failing name.Success conditionYou can turn bare names on, and say what you gave up to get them.
Troubleshooting
A script that worked on your machine pulls a different image in CI.
Why: Locally you had a cached image matching the bare name; the runner did not, so the alias table or the search list resolved it somewhere else.
Fix:Fully qualify every image reference.
podman images --format '{{.Repository}}'on both machines shows the divergence immediately.hello-worldgives Podman's greeting rather than Docker's.Why: Not a fault.
shortnames.confmaps it toquay.io/podman/hello.Fix:
podman pull docker.io/library/hello-worldfor the Docker one.In an interactive terminal Podman asks you to choose a registry instead of failing.
Why: With a search list of more than one registry and no alias, Podman prompts. With no TTY it cannot, so it errors.
Fix:Expected behaviour. Your choice is cached in
~/.cache/containers/short-name-aliases.conf, which then makes your machine behave differently from a colleague's - another reason to qualify names.You want an alias without editing the shipped file.
Why:
shortnames.confis package-managed and an upgrade will overwrite it.Fix:Drop your own file in
/etc/containers/registries.conf.d/with a higher numeric prefix. Files are read in order, so99-wins.