{"record":{"id":"06c384e624a4dd5c","repo":"GoogleContainerTools/jib","slug":"unauthorized-for-serverurl-imagename","errorCode":null,"errorMessage":"Unauthorized for ${serverUrl}/${imageName}","messagePattern":"Unauthorized for (.+?)/(.+?)","errorType":"http","errorClass":"RegistryUnauthorizedException","httpStatus":403,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java","lineNumber":156,"sourceCode":"        httpClient.call(registryEndpointProvider.getHttpMethod(), url, requestBuilder.build())) {\n\n      return registryEndpointProvider.handleResponse(response);\n\n    } catch (ResponseException ex) {\n      // First, see if the endpoint provider handles an exception as an expected response.\n      try {\n        return registryEndpointProvider.handleHttpResponseException(ex);\n\n      } catch (ResponseException responseException) {\n        if (responseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_BAD_REQUEST\n            || responseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND\n            || responseException.getStatusCode()\n                == HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED) {\n          // The name or reference was invalid.\n          throw newRegistryErrorException(responseException);\n\n        } else if (responseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_FORBIDDEN) {\n          throw new RegistryUnauthorizedException(serverUrl, imageName, responseException);\n\n        } else if (responseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_UNAUTHORIZED) {\n          if (responseException.requestAuthorizationCleared()) {\n            throw new RegistryCredentialsNotSentException(serverUrl, imageName);\n          } else {\n            // Credentials are either missing or wrong.\n            throw new RegistryUnauthorizedException(serverUrl, imageName, responseException);\n          }\n\n        } else {\n          // Unknown\n          throw responseException;\n        }\n      }\n\n    } catch (IOException ex) {\n      logError(\"I/O error for image [\" + serverUrl + \"/\" + imageName + \"]:\");\n      logError(\"    \" + ex.getClass().getName());","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java#L138-L174","documentation":"RegistryEndpointCaller translates registry HTTP 401 responses into RegistryUnauthorizedException ('Unauthorized for <serverUrl>/<imageName>') when credentials were present but rejected. If the response indicates authorization was cleared, it instead throws RegistryCredentialsNotSentException; this error is the missing/wrong-credentials case.","triggerScenarios":"A registry API call (manifest pull/push, blob pull/push) receives HTTP 401 (STATUS_CODE_UNAUTHORIZED) from the registry without the requestAuthorizationCleared flag during call().","commonSituations":"Expired or wrong credentials in docker config/credential helper; token lacks required scope (e.g., pulling from another repo's namespace); service account revoked; pushing to a private repo with anonymous credentials.","solutions":["Re-run 'docker login <registry>' or refresh the credential helper's token","Verify the account has the needed scope for the exact repository (pull vs push vs cross-mount)","If using Jib's auth parameters (authUsername/authPassword), confirm they are correct and not expired","For cross-repo blob mounts, ensure access to the source repository or disable cross-repo mounts"],"exampleFix":"// before: expired token in CI\ndocker login registry.example.com // with stale creds\n// after: refresh credentials before build\necho \"$NEW_TOKEN\" | docker login registry.example.com -u oauth2accesstoken --password-stdin","handlingStrategy":"try-catch","validationCode":"// verify credentials work against the registry API before the build\ncurl -s -o /dev/null -w '%{http_code}' -u user:pass https://registry.example.com/v2/my/repo/manifests/latest","typeGuard":null,"tryCatchPattern":"try { ...registry ops...; } catch (RegistryUnauthorizedException e) { throw new BuildException(\"Credentials rejected for \" + registry + \"/\" + repo + \" — re-login\", e); }","preventionTips":["Refresh tokens/credentials before long CI pipelines","Confirm the account scope covers the exact repository path","Check token expiry times vs build duration"],"tags":["registry","unauthorized","authentication"],"backgroundTag":"authentication-required","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}