Issue Description
I have a local container registry behind an nginx proxy that is configured as follows:
- GET, HEAD, and OPTIONS requests do not require authentication;
- every other HTTP method requires HTTP basic authentication.
The idea is that everyone can pull, but only authenticated users can push.
Now I've logged into the registry with podman login (that is always successful, also for wrong credentials, since the requests it does do not require authentication), but when I try to push an image with podman push it fails:
% podman --log-level=debug push myregistry.local/tests/hello-world:latest
INFO[0000] podman filtering at log level debug
DEBU[0000] Called push.PersistentPreRunE(podman --log-level=debug push myregistry.local/tests/hello-world:latest)
DEBU[0000] SSH Ident Key "/Users/me/.local/share/containers/podman/machine/machine" SHA256:21Nl633r+TBVZjIpNYTam9FgZHdNsuOJRNTCDIejQn4 ssh-ed25519
DEBU[0000] DoRequest Method: GET URI: http://d/v6.0.1/libpod/_ping
DEBU[0000] Found credentials for myregistry.local in credential helper containers-auth.json in file /Users/me/.config/containers/auth.json
DEBU[0000] DoRequest Method: POST URI: http://d/v6.0.1/libpod/images/myregistry.local/tests/hello-world:latest/push
Getting image source signatures
Copying blob sha256:55f6d36790cbd258a2173e1599268519414f9973696bcfc0f5193c1accee0951
Error: writing blob: initiating layer upload to /v2/tests/hello-world/blobs/uploads/ in myregistry.local: authentication required
DEBU[0000] Shutting down engines
The nginx log:
192.168.1.10 - - [22/Jul/2026:11:51:18 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "containers/5.34.1 (github.com/containers/image)" "-"
192.168.1.10 - - [22/Jul/2026:11:51:18 +0000] "HEAD /v2/tests/hello-world/blobs/sha256:55f6d36790cbd258a2173e1599268519414f9973696bcfc0f5193c1accee0951 HTTP/1.1" 404 0 "-" "containers/5.34.1 (github.com/containers/image)" "-"
192.168.1.10 - - [22/Jul/2026:11:51:18 +0000] "HEAD /v2/tests/hello-world/blobs/sha256:1ff9adeff4443b503b304e7aa4c37bb90762947125f4a522b370162a7492ff47 HTTP/1.1" 404 0 "-" "containers/5.34.1 (github.com/containers/image)" "-"
192.168.1.10 - - [22/Jul/2026:11:51:18 +0000] "POST /v2/tests/hello-world/blobs/uploads/ HTTP/1.1" 401 179 "-" "containers/5.34.1 (github.com/containers/image)" "-"
As you can see, the GET/HEAD requests just work, and from that podman apparently infers that the POST request should also just work. When the POST request returns 401, instead of re-trying with the stored credentials, it simply fails.
(I also temporarily changed the nginx log output to debug format, and it explicitly confirmed no user/password was provided for basic authentication for the POST - so it explicitly wasn't a typo in the credentials, but simply no Authorization header got sent.)
Steps to reproduce the issue
Steps to reproduce the issue
- Set up a registry where GET/HEAD/OPTIONS can be done by any user, but other HTTP methods require authorization
- Log into the registry with
podman login
- Try to push an image with
podman push
Describe the results you received
podman push fails, and the HTTP server log shows that podman simply gave up after retrieving a 401, despite it having credentials it can use.
Describe the results you expected
I can push the image. (Or at least I would get a step further, namely that after the 401 podman push tries again with an Authorization header.)
podman info output
(I also tried this with a different podman version on a Linux box, with the same result.)
Client:
APIVersion: 6.0.2
BuildOrigin: brew
Built: 1784664683
BuiltTime: Tue Jul 21 22:11:23 2026
GitCommit: ""
GoVersion: go1.26.5
Os: darwin
OsArch: darwin/arm64
Version: 6.0.2
host:
arch: arm64
buildahVersion: 1.39.2
cdiSpecDirs: null
cgroupControllers:
- cpuset
- cpu
- io
- memory
- pids
- rdma
- misc
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon-2.1.12-3.fc41.aarch64
path: /usr/bin/conmon
version: 'conmon version 2.1.12, commit: '
cpuUtilization:
idlePercent: 96.9
systemPercent: 1.84
userPercent: 1.26
cpus: 6
databaseBackend: sqlite
distribution:
distribution: fedora
variant: coreos
version: "41"
eventLogger: journald
freeLocks: 2047
hostname: localhost.localdomain
idMappings:
gidmap: null
uidmap: null
kernel: 6.12.13-200.fc41.aarch64
linkmode: dynamic
logDriver: journald
memFree: 3015950336
memTotal: 3791691776
networkBackend: netavark
networkBackendInfo:
backend: netavark
dns:
package: aardvark-dns-1.14.0-1.fc41.aarch64
path: /usr/libexec/podman/aardvark-dns
version: aardvark-dns 1.14.0
package: netavark-1.14.0-1.fc41.aarch64
path: /usr/libexec/podman/netavark
version: netavark 1.14.0
ociRuntime:
name: crun
package: crun-1.20-2.fc41.aarch64
path: /usr/bin/crun
version: |-
crun version 1.20
commit: 9c9a76ac11994701dd666c4f0b869ceffb599a66
rundir: /run/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +LIBKRUN +WASM:wasmedge +YAJL
os: linux
pasta:
executable: /usr/bin/pasta
package: passt-0^20250121.g4f2c8e7-2.fc41.aarch64
version: |
pasta 0^20250121.g4f2c8e7-2.fc41.aarch64-pasta
Copyright Red Hat
GNU General Public License, version 2 or later
<https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
remoteSocket:
exists: true
path: unix:///run/podman/podman.sock
rootlessNetworkCmd: pasta
rootlessPortForwarder: ""
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: false
seccompEnabled: true
seccompProfilePath: /usr/share/containers/seccomp.json
selinuxEnabled: true
serviceIsRemote: true
swapFree: 0
swapTotal: 0
uptime: 0h 0m 28.00s
variant: v8
plugins:
authorization: null
log:
- k8s-file
- none
- passthrough
- journald
network:
- bridge
- macvlan
- ipvlan
volume:
- local
registries:
search:
- docker.io
store:
containerStore:
number: 1
paused: 0
running: 0
stopped: 1
graphDriverName: overlay
graphOptions:
overlay.additionalImageStores:
- /usr/lib/containers/storage
overlay.imagestore: /usr/lib/containers/storage
overlay.mountopt: nodev,metacopy=on
graphRoot: /var/lib/containers/storage
graphRootAllocated: 98899800064
graphRootUsed: 8574558208
graphStatus:
Backing Filesystem: xfs
Native Overlay Diff: "false"
Supports d_type: "true"
Supports shifting: "true"
Supports volatile: "true"
Using metacopy: "true"
imageCopyTmpDir: /var/tmp
imageStore:
number: 16
runRoot: /run/containers/storage
transientStore: false
volumePath: /var/lib/containers/storage/volumes
version:
APIVersion: 5.4.1
BuildOrigin: Fedora Project
Built: 1741651200
BuiltTime: Tue Mar 11 01:00:00 2025
GitCommit: b79bc8afe796cba51dd906270a7e1056ccdfcf9e
GoVersion: go1.23.7
Os: linux
OsArch: linux/arm64
Version: 5.4.1
Podman in a container
No
Privileged Or Rootless
Rootless
Upstream Latest Release
Yes
Additional environment details
Additional information
Issue Description
I have a local container registry behind an nginx proxy that is configured as follows:
The idea is that everyone can pull, but only authenticated users can push.
Now I've logged into the registry with
podman login(that is always successful, also for wrong credentials, since the requests it does do not require authentication), but when I try to push an image withpodman pushit fails:The nginx log:
As you can see, the GET/HEAD requests just work, and from that podman apparently infers that the POST request should also just work. When the POST request returns 401, instead of re-trying with the stored credentials, it simply fails.
(I also temporarily changed the nginx log output to
debugformat, and it explicitly confirmedno user/password was provided for basic authenticationfor the POST - so it explicitly wasn't a typo in the credentials, but simply noAuthorizationheader got sent.)Steps to reproduce the issue
Steps to reproduce the issue
podman loginpodman pushDescribe the results you received
podman pushfails, and the HTTP server log shows that podman simply gave up after retrieving a 401, despite it having credentials it can use.Describe the results you expected
I can push the image. (Or at least I would get a step further, namely that after the 401
podman pushtries again with anAuthorizationheader.)podman info output
Podman in a container
No
Privileged Or Rootless
Rootless
Upstream Latest Release
Yes
Additional environment details
Additional information