GoogleContainerTools/skaffold · error
unable to connect to Kubernetes: %w
Error message
unable to connect to Kubernetes: %w
What it means
Wraps the failure from kubernetes.FailIfClusterIsNotReachable during Deploy. Skaffold pre-checks cluster reachability before deploying so the user gets a clear 'unable to connect to Kubernetes' message instead of a confusing helm/kubectl error later in the deploy pipeline. The wrapped error carries the underlying cause (DNS, auth, context).
Source
Thrown at pkg/skaffold/deploy/helm/helm.go:251
h.localImages = images
}
func (h *Deployer) TrackBuildArtifacts(builds, deployedImages []graph.Artifact) {
deployutil.AddTagsToPodSelector(builds, deployedImages, h.podSelector)
h.logger.RegisterArtifacts(builds)
}
// Deploy deploys the build results to the Kubernetes cluster
func (h *Deployer) Deploy(ctx context.Context, out io.Writer, builds []graph.Artifact, _ manifest.ManifestListByConfig) error {
ctx, endTrace := instrumentation.StartTrace(ctx, "Deploy", map[string]string{
"DeployerType": "helm",
})
defer endTrace()
// Check that the cluster is reachable.
// This gives a better error message when the cluster can't be reached.
if err := kubernetes.FailIfClusterIsNotReachable(h.kubeContext); err != nil {
return fmt.Errorf("unable to connect to Kubernetes: %w", err)
}
childCtx, endTrace := instrumentation.StartTrace(ctx, "Deploy_LoadImages")
if err := h.imageLoader.LoadImages(childCtx, out, h.localImages, h.originalImages, builds); err != nil {
endTrace(instrumentation.TraceEndError(err))
return err
}
endTrace()
olog.Entry(ctx).Infof("Deploying with helm v%s ...", h.helmVersion)
dependencyGraph, err := NewDependencyGraph(h.Releases)
if err != nil {
return fmt.Errorf("unable to create dependency graph: %w", err)
}
levelByLevelReleases, err := dependencyGraph.GetReleasesByLevel()
if err != nil {View on GitHub (pinned to a1189de023)
Solutions
- Run `kubectl cluster-info --context <kubeContext>` to verify the cluster is reachable with the same kubeconfig
- Start or reconnect the cluster (minikube start, kind cluster create, connect VPN)
- Check the `kube-context` value in skaffold.yaml matches `kubectl config get-contexts`
- Refresh credentials (gcloud container clusters get-credentials / aws eks update-kubeconfig)
Example fix
// before
.deploy:
script: skaffold run
// after
.deploy:
script:
- kubectl config use-context $KUBE_CONTEXT
- kubectl cluster-info # fail fast if unreachable
- skaffold run Defensive patterns
Strategy: try-catch
Validate before calling
import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func validateCluster(kubeContext string) error {
cfg, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{CurrentContext: kubeContext}).ClientConfig()
if err != nil { return err }
_, err = kubernetes.NewForConfig(cfg).Discovery().ServerVersion()
return err
} Try / catch
err := deployer.Deploy(ctx, out)
var connErr error
if errors.As(err, &connErr) && strings.Contains(err.Error(), "unable to connect to Kubernetes") {
// check kubeconfig, VPN, credentials, then retry once
} Prevention
- Run `kubectl cluster-info` in preflight before deploying
- Pin kubeContext in skaffold.yaml and verify it exists via `kubectl config get-contexts`
- Refresh cloud credentials in CI before each deploy
- Alert on API-server reachability in the deploy environment
When it happens
Trigger: Calling Deployer.Deploy when the kubeconfig context points to an unreachable API server, credentials are expired/missing, or the kubeContext name does not exist.
Common situations: VPN not connected to a private cluster, KIND/minikube cluster stopped, GKE/EKS token expired, typo in kubectl context name, ~/.kube/config absent in CI containers.
Related errors
- strings.Join(errMsgs, "\n") (joined helm cleanup error messa
- failed to deploy: %w
- unable to connect to Kubernetes: %w
- unable to connect to Kubernetes: %w
- starting logger: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/7c9f5bad2fbd054e.
Report an issue: GitHub.