Skip to content

bootBuildImage on Windows cannot execute Docker credential helpers shipped as .cmd (e.g. gcloud) #48961

@bwoester

Description

@bwoester

Summary

On Windows, gradle task bootBuildImage fails to invoke Docker credential helpers when the helper is available as a .cmd file (for example docker-credential-gcloud.cmd from the Google Cloud SDK). This causes pushes to fail as unauthenticated even though docker push on the CLI succeeds with the same Docker configuration.

This appears to be a platform-specific behavior difference rather than a general usage issue.


Environment

  • Windows 11
  • Spring Boot 4.0.1
  • Docker Desktop
  • Google Cloud SDK installed
  • Spring Boot Gradle plugin (bootBuildImage)
  • Registry: Google Artifact Registry (europe-west3-docker.pkg.dev) - although I don't think the registry matters; it's how the credentials helper is deployed

Docker configuration

%USERPROFILE%\.docker\config.json:

    {
      "auths": {},
      "credsStore": "desktop",
      "credHelpers": {
        "europe-west3-docker.pkg.dev": "gcloud"
      }
    }

On Windows, the Google Cloud SDK provides the helper as:

docker-credential-gcloud.cmd

Observed behavior

bootBuildImage builds the image successfully but fails during the push phase.

Debugging into the gradle plugin, I can see an exception occur, when the plugin tries to call the credentials helper:

"java.io.IOException: Cannot run program "docker-credential-gcloud": CreateProcess error=2, The system cannot find the file specified"

The relevant part of the stack trace is:

0 = {StackTraceElement@18152} "java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1112)"
1 = {StackTraceElement@18153} "java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1046)"
2 = {StackTraceElement@18154} "org.gradle.internal.classpath.Instrumented.start(Instrumented.java:315)"
3 = {StackTraceElement@18155} "org.springframework.boot.buildpack.platform.docker.configuration.CredentialHelper.start(CredentialHelper.java:88)"
4 = {StackTraceElement@18156} "org.springframework.boot.buildpack.platform.docker.configuration.CredentialHelper.get(CredentialHelper.java:54)"
5 = {StackTraceElement@18157} "org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfigAuthentication.computeCredentialsFromHelper(DockerRegistryConfigAuthentication.java:129)"
6 = {StackTraceElement@18158} "java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1724)"
7 = {StackTraceElement@18159} "org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfigAuthentication.getCredentialsFromHelper(DockerRegistryConfigAuthentication.java:122)"
8 = {StackTraceElement@18160} "org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfigAuthentication.getAuthentication(DockerRegistryConfigAuthentication.java:89)"
9 = {StackTraceElement@18161} "org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryConfigAuthentication.getAuthHeader(DockerRegistryConfigAuthentication.java:79)"
10 = {StackTraceElement@18162} "org.springframework.boot.buildpack.platform.build.Builder.authHeader(Builder.java:224)"
11 = {StackTraceElement@18163} "org.springframework.boot.buildpack.platform.build.Builder.pushImage(Builder.java:217)"

The resulting Docker push request contains an empty X-Registry-Auth header, and the registry responds with an unauthenticated error.

This results in the gradle error message:

Execution failed for task ':bootBuildImage'.
> Error response received when pushing image: error from registry: Unauthenticated request. Unauthenticated requests do not have permission "artifactregistry.repositories.uploadArtifacts" on resource "*****" (or it may not exist)

(I think this could also be improved, by mentioning that a credentials helper could not be executed)


Expected behavior

The Docker CLI successfully pushes the same image using the same Docker configuration. It resolves and executes docker-credential-gcloud.cmd correctly (via Windows executable resolution / PATHEXT behavior).

Since bootBuildImage documents support for Docker credential helpers, I expected the helper to be resolved in the same way on Windows, or for this limitation to be documented.


Workaround

Changing the credential helper entry to explicitly include the file extension works:

{
  "credHelpers": {
    "europe-west3-docker.pkg.dev": "gcloud.cmd"
  }
}

With this change, bootBuildImage successfully authenticates and pushes the image.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: supersededAn issue that has been superseded by anothertype: bugA general bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions