{"record":{"id":"babe8fef88163338","repo":"GoogleContainerTools/skaffold","slug":"unable-to-connect-to-kubernetes-w","errorCode":null,"errorMessage":"unable to connect to Kubernetes: %w","messagePattern":"unable to connect to Kubernetes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/actions/k8sjob/exec_env.go","lineNumber":101,"sourceCode":"\tfor k, v := range envMap {\n\t\tenvVars = append(envVars, corev1.EnvVar{Name: k, Value: v})\n\t}\n\n\treturn &ExecEnv{\n\t\tkubectl:      &kubectl,\n\t\tlogger:       logger,\n\t\ttracker:      tracker,\n\t\tnamespace:    namespace,\n\t\tlabeller:     labeller,\n\t\timageLoader:  k8scomponents.NewImageLoader(cfg, kubectl.CLI),\n\t\tacsCfgByName: acsCfgByName,\n\t\tenvVars:      envVars,\n\t}\n}\n\nfunc (e ExecEnv) PrepareActions(ctx context.Context, out io.Writer, allbuilds, localImgs []graph.Artifact, acsNames []string) ([]actions.Action, error) {\n\tif err := kubernetes.FailIfClusterIsNotReachable(e.kubectl.KubeContext); err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to connect to Kubernetes: %w\", err)\n\t}\n\n\tif err := e.imageLoader.LoadImages(ctx, out, localImgs, localImgs, localImgs); err != nil {\n\t\treturn nil, err\n\t}\n\n\te.logger.Start(ctx, out)\n\n\treturn e.createActions(allbuilds, acsNames)\n}\n\nfunc (e ExecEnv) Cleanup(ctx context.Context, out io.Writer) error {\n\treturn nil\n}\n\nfunc (e ExecEnv) Stop() {\n\t// This is to drain the logs from the succeeded jobs. Failed jobs were already removed from the cluster.\n\te.logger.Stop()","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/actions/k8sjob/exec_env.go#L83-L119","documentation":"The k8sjob action exec environment first verifies the target Kubernetes cluster is reachable via kubernetes.FailIfClusterIsNotReachable using the configured kubecontext. If the API server cannot be contacted, PrepareActions returns this wrapped error before loading images or creating jobs.","triggerScenarios":"Running skaffold actions in KubernetesCluster execution mode; FailIfClusterIsNotReachable fails due to no cluster running (kind/minikube stopped), wrong --kube-context, expired credentials, or no network route to the API server.","commonSituations":"kind cluster deleted or minikube not started; VPN off so the API server IP unreachable; kubeconfig context pointing to a stale cluster after cloud provider rotation; OIDC/token expired.","solutions":["Confirm the context and connectivity: kubectl config get-contexts; kubectl cluster-info --context <ctx>.","Start or recreate the local cluster (minikube start / kind create cluster) if it is stopped or deleted.","Refresh credentials (re-authenticate with your cloud provider / kubectl oidc-login) if the kubeconfig token expired."],"exampleFix":"// before\nskaffold run  # fails: kind cluster stopped\n// after\nkind create cluster  # or: minikube start\nkubectl cluster-info  # verify reachable\nskaffold run","handlingStrategy":"validation","validationCode":"// Fail fast if the target cluster is not reachable\nkubectl cluster-info --context <ctx> > /dev/null || { echo 'cluster unreachable'; exit 1; }","typeGuard":null,"tryCatchPattern":"try {\n  await skaffold.run(...);\n} catch (e) {\n  if (/unable to connect to Kubernetes/.test(String(e))) {\n    // start local cluster / refresh creds, then retry\n    execSync('minikube start');\n    await skaffold.run(...);\n    return;\n  }\n  throw e;\n}","preventionTips":["Start kind/minikube in CI before skaffold steps","Run kubectl cluster-info as a preflight gate","Keep cloud credentials refreshed (token expiry) for remote clusters"],"tags":["kubernetes","connectivity","skaffold","custom-actions"],"backgroundTag":"cluster-unreachable","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}