GoogleContainerTools/skaffold · error

error getting docker client: %s

Error message

error getting docker client: %s

What it means

This error is wrapped by newEnvAPIClient when the Docker SDK's client.New(opts...) call fails to construct a Docker client. Skaffold builds the client from resolved environment options (DOCKER_HOST, certs, etc.) and adds API version negotiation; any failure at this stage means the Docker client itself could not be created, typically due to an invalid Docker host address or bad TLS configuration. The underlying SDK error is appended via %s.

Source

Thrown at pkg/skaffold/docker/client.go:138

		command := exec.Command("docker", "context", "inspect", "--format", "{{.Endpoints.docker.Host}}")
		out, err := util.RunCmdOut(context.TODO(), command)
		if err != nil {
			// docker cli not installed.
			log.Entry(context.TODO()).Warnf("Could not get docker context: %s, falling back to the default docker host", err)
		} else {
			s := strings.TrimSpace(string(out))
			// output can be empty if user uses docker as alias for podman
			if len(s) > 0 {
				opts = append(opts, client.WithHost(s))
			}
		}
	}

	opts = append(opts, client.WithAPIVersionNegotiation())
	cli, err := client.New(opts...)
	if err != nil {
		return nil, nil, fmt.Errorf("error getting docker client: %s", err)
	}

	return nil, cli, nil
}

type ExitCoder interface {
	ExitCode() int
}

// newMinikubeAPIClient returns a docker client using the environment variables
// provided by minikube.
func newMinikubeAPIClient(ctx context.Context, minikubeProfile string) ([]string, client.APIClient, error) {
	env, err := getMinikubeDockerEnv(ctx, minikubeProfile)
	if err != nil {
		// When minikube uses the infamous `none` driver, `minikube docker-env` will exit with
		// code 51 (>= 1.13.0) or 64 (< 1.13.0).  Note that exit code 51 was unused prior to 1.13.0
		// so it is safe to check here without knowing the minikube version.
		var exitError ExitCoder

View on GitHub (pinned to a1189de023)

Solutions

  1. Check DOCKER_HOST: run 'docker context ls' or 'echo $DOCKER_HOST' and fix malformed values (must be unix:///path or tcp://host:port).
  2. If using TLS, verify DOCKER_CERT_PATH contains ca.pem, cert.pem, key.pem and DOCKER_TLS_VERIFY=1 is set correctly.
  3. Unset conflicting env vars ('unset DOCKER_HOST DOCKER_TLS_VERIFY DOCKER_CERT_PATH') to fall back to the default local socket.
  4. Run 'docker version' with the same environment to confirm the Docker CLI can connect; fix whatever it reports.
  5. If it came from a minikube profile, re-run 'minikube -p <profile> docker-env' and re-export the values.

Example fix

// before
export DOCKER_HOST="http://localhost:2375"
// after
export DOCKER_HOST="tcp://localhost:2375"
Defensive patterns

Strategy: validation

Validate before calling

host := os.Getenv("DOCKER_HOST")
if host != "" {
    u, err := url.Parse(host)
    if err != nil || (u.Scheme != "unix" && u.Scheme != "tcp" && u.Scheme != "npipe" && u.Scheme != "ssh") {
        return fmt.Errorf("invalid DOCKER_HOST %q: must be unix://, tcp://, npipe:// or ssh://", host)
    }
}
if os.Getenv("DOCKER_TLS_VERIFY") != "" {
    for _, f := range []string{"ca.pem", "cert.pem", "key.pem"} {
        if _, err := os.Stat(filepath.Join(os.Getenv("DOCKER_CERT_PATH"), f)); err != nil {
            return fmt.Errorf("missing TLS cert %s in DOCKER_CERT_PATH", f)
        }
    }
}

Type guard

func dockerHostValid(host string) bool {
    if host == "" {
        return true
    }
    u, err := url.Parse(host)
    return err == nil && u.Scheme != ""
}

Try / catch

cli, err := newAPIClient(ctx, cfg)
if err != nil {
    var derr *dockerClientError
    if errors.As(err, &derr) {
        log.Fatalf("Docker client setup failed: %v — check DOCKER_HOST/DOCKER_CERT_PATH", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling newAPIClient, newMinikubeAPIClient, or the anonymous caller path when client.New(opts...) returns an error — e.g. DOCKER_HOST set to a malformed URL like 'tcp://:2375', an unsupported scheme, or invalid client cert/key paths passed as options.

Common situations: DOCKER_HOST contains a typo or unsupported protocol (http:// instead of tcp://); DOCKER_TLS_VERIFY/DOCKER_CERT_PATH point to missing or unreadable certificate files; a minikube docker-env export produced a bad DOCKER_HOST value; Docker SDK cannot parse the connection string.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/92d1b51b471d1a02. Report an issue: GitHub.