{"record":{"id":"3b28027511c471a7","repo":"GoogleContainerTools/jib","slug":"did-not-get-token-in-authentication-response-from","errorCode":null,"errorMessage":"Did not get token in authentication response from ${authenticationUrl}; parameters: ${authRequestParameters}","messagePattern":"Did not get token in authentication response from (.+?); parameters: (.+?)","errorType":"exception","errorClass":"RegistryAuthenticationFailedException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java","lineNumber":289,"sourceCode":"              .setUserAgent(userAgent);\n\n      if (isOAuth2Auth(credential)) {\n        String parameters = getAuthRequestParameters(credential, repositoryScopes);\n        requestBuilder.setBody(\n            new BlobHttpContent(Blobs.from(parameters), MediaType.FORM_DATA.toString()));\n      } else if (credential != null) {\n        requestBuilder.setAuthorization(\n            Authorization.fromBasicCredentials(credential.getUsername(), credential.getPassword()));\n      }\n\n      String httpMethod = isOAuth2Auth(credential) ? HttpMethods.POST : HttpMethods.GET;\n      try (Response response = httpClient.call(httpMethod, url, requestBuilder.build())) {\n\n        AuthenticationResponseTemplate responseJson =\n            JsonTemplateMapper.readJson(response.getBody(), AuthenticationResponseTemplate.class);\n\n        if (responseJson.getToken() == null) {\n          throw new RegistryAuthenticationFailedException(\n              registryUrl,\n              imageName,\n              \"Did not get token in authentication response from \"\n                  + getAuthenticationUrl(credential, repositoryScopes)\n                  + \"; parameters: \"\n                  + getAuthRequestParameters(credential, repositoryScopes));\n        }\n        return Authorization.fromBearerToken(responseJson.getToken());\n      }\n\n    } catch (ResponseException ex) {\n      if (ex.getStatusCode() == HttpStatusCodes.STATUS_CODE_UNAUTHORIZED\n          && ex.requestAuthorizationCleared()) {\n        throw new RegistryCredentialsNotSentException(registryUrl, imageName);\n      }\n      throw new RegistryAuthenticationFailedException(registryUrl, imageName, ex);\n\n    } catch (IOException ex) {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryAuthenticator.java#L271-L307","documentation":"RegistryAuthenticator.authenticate performs the OAuth2/token exchange against the registry's auth server and expects a JSON body containing a token field. If the response parses but has no token, RegistryAuthenticationFailedException is thrown with the authentication URL and request parameters, since the flow cannot continue without a bearer token.","triggerScenarios":"The auth server (e.g., the /service/token endpoint) returns 200 with a JSON body lacking a 'token' (or the expected fields) after calling authenticate with the credential and repository scopes.","commonSituations":"Pointing Jib at a custom auth endpoint that returns a different JSON schema (e.g., 'access_token' only with no token mapping, or an HTML error page that accidentally parses); misconfigured registry-wide auth (registry.auth) settings in build config; private registry gateways returning soft-200 responses.","solutions":["Verify the registry's auth URL actually returns {\"token\": \"...\"} for the given credentials","Fix credentials (username/password) — some auth servers return empty bodies on bad credentials","Check custom authUrlTokenPattern/registry auth configuration in the build tool matches your registry (e.g., for Artifactory, Harbor)","Capture the raw auth-server response (curl the authUrl with the same parameters) to see what it actually returns"],"exampleFix":"// before: wrong custom auth URL config\nRegistryAuthenticator.fromAuthenticationMethod(\"Bearer realm=\\\"https://old-auth.example.com/token\\\"\", ...);\n// after: point at the correct realm advertised by the registry\nRegistryAuthenticator.fromAuthenticationMethod(\"Bearer realm=\\\"https://auth.example.com/service/token\\\",service=\\\"registry.docker.io\\\"\", ...);","handlingStrategy":"validation","validationCode":"// sanity check the auth realm returns a token schema\ncurl -s \"https://auth.example.com/service/token?service=registry&scope=repository:my/repo:pull\" -u user:pass | jq '.token'","typeGuard":null,"tryCatchPattern":"try { authenticator.authenticate(pullScope); } catch (RegistryAuthenticationFailedException e) { throw new BuildException(\"Auth server did not return a token; check auth config\", e); }","preventionTips":["Verify registry auth realm configuration against your registry vendor's docs","Test the token endpoint manually with curl before wiring it into builds","Keep registry/auth server versions current"],"tags":["registry","authentication","token"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}