Solution

ARTIFACTORY: What to do when docker pulls work, but docker pushes fail with ‘unauthorized”

AuthorFullName__c
Nir Ovadia
articleNumber
000005623
ft:sourceType
Salesforce
FirstPublishedDate
2023-03-19T09:52:14Z
lastModifiedDate
2023-03-19T10:59:02Z
VersionNumber
1
Thankfully, this is actually a simple issue we see occasionally with a simple fix. The issue here is due to the headers. Docker pays more attention to the proper headers, so issues there can cause unexpected behaviors. In this case, the issue is that a header is being resolved to the wrong protocol.

Usually, a reverse proxy for Artifactory would have the following headers (the following example is in NGINX)
proxy_set_header    X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host;
proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header    X-Forwarded-Port  $server_port;

And here the protocol and ports are being set automatically by the reverse proxy application. The thing is, depending on the networking, this could be getting set incorrectly. For example, if the connection is HTTPS but the load balancer is handling the SSL part, and the proxy sets these values as HTTP/port 80 since it doesn’t see any HTTPS elements. This is where the issue occurs, where these variables are being set incorrectly and the docker push command successfully creates a connection, but then errors out while it uses some of these headers for the push. The fix is pretty simple, we just need to set the $http_x_forwarded_proto and $server_port variables to what they’re supposed to be. Since these headers are in my HTTPS block, I set them to HTTPS/443
proxy_set_header    X-JFrog-Override-Base-Url https://$host;
proxy_set_header    X-Forwarded-Proto https;
proxy_set_header    X-Forwarded-Port  443;

And reload NGINX. The variables don’t need to be used as we have a specific HTTPS block that should always be HTTPS (or an HTTP block that should always be HTTP), so you can hardcode these values. You could also do something like
set $http_x_forwarded_proto https;

to set a variable for a section, but you will need to play around with the scopes to make sure you’re applying this only to what you want to change. After this change (and restart of the reverse proxy service), the docker push command should work as intended.

User-added image