{"record":{"id":"ab8eb57f97110c2c","repo":"helm/helm","slug":"kubernetes-cluster-unreachable","errorCode":null,"errorMessage":"kubernetes cluster unreachable","messagePattern":"kubernetes cluster unreachable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/kube/client.go","lineNumber":258,"sourceCode":"func (c *Client) getKubeClient() (kubernetes.Interface, error) {\n\tif c.kubeClient != nil {\n\t\treturn c.kubeClient, nil\n\t}\n\tkc, err := c.Factory.KubernetesClientSet()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.kubeClient = kc\n\treturn c.kubeClient, nil\n}\n\n// IsReachable tests connectivity to the cluster.\nfunc (c *Client) IsReachable() error {\n\tclient, err := c.getKubeClient()\n\tif errors.Is(err, genericclioptions.ErrEmptyConfig) {\n\t\t// re-replace kubernetes ErrEmptyConfig error with a friendly error\n\t\t// moar workarounds for Kubernetes API breaking.\n\t\treturn errors.New(\"kubernetes cluster unreachable\")\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kubernetes cluster unreachable: %w\", err)\n\t}\n\tif _, err := client.Discovery().ServerVersion(); err != nil {\n\t\treturn fmt.Errorf(\"kubernetes cluster unreachable: %w\", err)\n\t}\n\treturn nil\n}\n\ntype clientCreateOptions struct {\n\tserverSideApply          bool\n\tforceConflicts           bool\n\tdryRun                   bool\n\tfieldValidationDirective FieldValidationDirective\n}\n\ntype ClientCreateOption func(*clientCreateOptions) error","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/helm/helm/blob/2a29f1770b62844b27197d2507377361d45ad7c0/pkg/kube/client.go#L240-L276","documentation":"Returned by Client.IsReachable (pkg/kube/client.go:258) when constructing the Kubernetes client fails with client-go's genericclioptions.ErrEmptyConfig — the kubeconfig is missing, empty, or has no usable current context. Helm deliberately replaces the cryptic ErrEmptyConfig with this friendly bare message (no wrapped detail). Other failures in IsReachable produce the wrapped variant \"kubernetes cluster unreachable: <err>\" from lines 261/264.","triggerScenarios":"kube.Client.IsReachable() with KUBECONFIG unset/pointing at a nonexistent file, an empty kubeconfig, or no current-context; this is the preflight check behind `helm install/upgrade` reporting \"Kubernetes cluster unreachable: ...\".","commonSituations":"CI containers without a kubeconfig mounted; wrong KUBECONFIG path; a fresh machine that never ran kubectl config; a kubeconfig whose current-context points at a removed cluster; SDK usage without passing a RESTClientGetter.","solutions":["Verify and regenerate kubeconfig: `kubectl config get-contexts` / `kubectl config use-context <name>`; check `echo $KUBECONFIG`","Point KUBECONFIG at a valid file or create one (minikube/kind/cluster setup writes it)","When using the SDK, pass a genericclioptions.RESTClientGetter (e.g. ConfigFlags with APIServer, BearerToken, CAFile set) instead of relying on the default config loading"],"exampleFix":"// before\nc := kube.New(nil) // relies on default kubeconfig discovery\nif err := c.IsReachable(); err != nil { return err }\n\n// after — explicit config\nflags := genericclioptions.NewConfigFlags(true)\nflags.APIServer = ptr.To(\"https://127.0.0.1:6443\")\nflags.BearerToken = ptr.To(\"...\")\nflags.CAFile = ptr.To(\"/path/ca.crt\")\nc := kube.New(flags)","handlingStrategy":"validation","validationCode":"// Validate kubeconfig usability before touching Helm\nfunc kubeconfigUsable() error {\n    if os.Getenv(\"KUBECONFIG\") == \"\" {\n        home, _ := os.UserHomeDir()\n        if _, err := os.Stat(filepath.Join(home, \".kube\", \"config\")); err != nil {\n            return errors.New(\"no kubeconfig found: set KUBECONFIG or create ~/.kube/config\")\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := c.IsReachable(); err != nil {\n    if strings.Contains(err.Error(), \"kubernetes cluster unreachable\") {\n        return fmt.Errorf(\"cannot reach cluster — check KUBECONFIG/context (kubectl get nodes): %w\", err)\n    }\n    return err\n}","preventionTips":["Fail fast in CI: assert kubectl config get-contexts succeeds before running helm/SDK operations","Pass an explicit RESTClientGetter when embedding Helm instead of relying on ambient kubeconfig discovery","Distinguish this no-config error from network failures: the bare message means no config; the ': err' variants mean config existed but connection failed"],"tags":["kubernetes","kubeconfig","connectivity","configuration","ci"],"backgroundTag":null,"analyzedSha":"2a29f1770b62844b27197d2507377361d45ad7c0","analyzedAt":"2026-08-15T22:02:47.490Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}