Moving Podman Images Without a Registry
`podman image scp localhost/multi:1 lab02::` copies an image host to host and prints `Loaded image`. Give it a raw `user@host::` instead of a named connection and it copies every blob and then fails.
Registries and Remote Hosts Guide 39 of 47 Intermediate
- 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.21 | Ubuntu 26.04 LTS | Primary Container Host | 2 Core | 4 GB | 50 GB |
| PODMAN02 | 192.168.0.22 | Ubuntu 26.04 LTS | Rootless and Remote Client Host | 2 Core | 4 GB | 50 GB |
Before you start
- guide 72 - the same ssh trust, in the other direction.
podman.socketenabled on the DESTINATION host.
-
The obvious form, which does not work
The documentation-shaped guess is a raw ssh destination:
podman image scp localhost/multi:1 sysadmin@192.168.0.22::And it half works, which is the annoying part. Every blob copies, then:
level=warning msg="Unknown connection name given. Please use system connection add to specify the default remote socket location" ... Copying blob sha256:6f09edfb3f6d... Writing manifest to image destination Error: failed to connect: ssh: handshake failed: EOFThe warning at the top is the real message and it arrives before the work rather than after.
image scpaddresses a named system connection, not a host - it needs the socket path and identity that a connection carries, and a bareuser@hostgives it neither.Note the destination's image list is still empty afterwards. The blobs went somewhere and the load never happened.
bash Example session podman images --format 'table {{.Repository}} {{.Tag}} {{.Size}}' localhost/multiREPOSITORY TAG SIZElocalhost/multi 1 8.66 MBlocalhost/multi builder 182 MBpodman images --format 'table {{.Repository}} {{.Tag}} {{.Size}}' localhost/multiREPOSITORY TAG SIZElocalhost/multi 1 8.66 MBlocalhost/multi builder 182 MBpodman image scp localhost/multi:1 sysadmin@192.168.0.22::time="2026-08-22T12:40:05Z" level=warning msg="Unknown connection name given. Please use system connection add to specify the default remote socket location"Copying blob sha256:6f09edfb3f6d7173733adc8eec8ea00626550dc6fc2dcf07d40e13f5c1e907c4Copying blob sha256:7da0375eb2ecd60c8f630fc42f4cc36c6d2b3923f404212810c167019169b092Copying config sha256:9f00b68fe5e6bb84503d42c233b5a42d492c28bca1305725319db6fa702e5f04Writing manifest to image destinationError: failed to connect: ssh: handshake failed: EOF[exit 125]Expected resultA source image, an empty destination, and blobs copied followed by a handshake failure.
Success conditionYou have seen the form that looks right and is not.
-
Name the destination first
Two things the destination needs: its own
podman.socketenabled, and a named connection pointing at it from the source.podman system connection add --identity ~/.ssh/id_ed25519 lab02 \ ssh://sysadmin@192.168.0.22/run/user/1000/podman/podman.sockNote the direction. guide 72 set up podman02 → podman01; this is podman01 → podman02, and the two are independent. ssh trust is not symmetric, and this is exactly what the first attempt was missing.
bash Example session systemctl --user is-active podman.socketactivepodman system connection add --identity ~/.ssh/id_ed25519 lab02 ssh://sysadmin@192.168.0.22/run/user/1000/podman/podman.sockpodman system connection lsName URI Identity Default ReadWritelab02 ssh://sysadmin@192.168.0.22:22/run/user/1000/podman/podman.sock /home/sysadmin/.ssh/id_ed25519 true trueExpected resultAn active socket on the destination, and a
lab02connection on the source.Success conditionThe source can name the destination.
-
Copy it, and run it there
$ podman image scp localhost/multi:1 lab02:: Copying blob sha256:6f09edfb3f6d... Writing manifest to image destination Loaded image: localhost/multi:1Loaded imageis the line the first attempt never reached. The destination now listslocalhost/multi:1at 8.66 MB, and running it there printscompiled in a stage that was thrown away- the multi-stage image from guide 33, now on a host that has never built anything.The name travels unchanged, including the
localhost/prefix from guide 30 - which reads oddly on the destination, since it came from somewhere else. Append a new name to retag on arrival:podman image scp localhost/multi:1 lab02::app:1.When this is the right tool: an air-gapped host, a one-off, a machine where standing up a registry is more work than the transfer. It goes over ssh, needs no daemon and no TLS certificate, and there is nothing left running afterwards.
When it is not: more than a couple of hosts, or anything repeated. It is a point-to-point copy with no deduplication between destinations and no record of what has which version - which is what a registry is for, and what guide 74 sets up.
podman saveandpodman loadremain the answer when the two machines cannot reach each other at all.bash Example session podman image scp localhost/multi:1 lab02::Copying blob sha256:6f09edfb3f6d7173733adc8eec8ea00626550dc6fc2dcf07d40e13f5c1e907c4Copying blob sha256:7da0375eb2ecd60c8f630fc42f4cc36c6d2b3923f404212810c167019169b092Copying config sha256:9f00b68fe5e6bb84503d42c233b5a42d492c28bca1305725319db6fa702e5f04Writing manifest to image destinationLoaded image: localhost/multi:1podman images --format 'table {{.Repository}} {{.Tag}} {{.Size}}' localhost/multiREPOSITORY TAG SIZElocalhost/multi 1 8.66 MBlocalhost/multi builder 182 MBpodman run --rm localhost/multi:1compiled in a stage that was thrown awayExpected result
Loaded image, the image listed on the destination, and its output when run there.Success conditionAn image built on one host is running on another, with no registry involved.
Troubleshooting
Unknown connection name given.Why: A raw
user@host::destination.Fix:
podman system connection adda name for the destination, then usename::.ssh: handshake failed: EOFafter the blobs copy.Why: The second connection - the one that loads the image - could not authenticate.
Fix:Confirm plain
sshworks from source to destination as that user, and that the connection's--identityis the key that is authorised.failed to connect: dial unix ... no such file.Why: The destination's socket is not enabled.
Fix:
systemctl --user enable --now podman.socketon the destination.The image arrives but under a name you did not want.
Why: The source name is preserved,
localhost/and all.Fix:Give a destination name:
podman image scp src:tag conn::newname:tag.