{"record":{"id":"1934cb80e5352058","repo":"derailed/k9s","slug":"no-connection-to-cached-dial","errorCode":null,"errorMessage":"no connection to cached dial","messagePattern":"no connection to cached dial","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/client.go","lineNumber":491,"sourceCode":"\t}\n\tc, err := kubernetes.NewForConfig(cfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ta.setClient(c)\n\n\treturn a.getClient(), nil\n}\n\n// RestConfig returns a rest api client.\nfunc (a *APIClient) RestConfig() (*restclient.Config, error) {\n\treturn a.config.RESTConfig()\n}\n\n// CachedDiscovery returns a cached discovery client.\nfunc (a *APIClient) CachedDiscovery() (*disk.CachedDiscoveryClient, error) {\n\tif !a.getConnOK() {\n\t\treturn nil, errors.New(\"no connection to cached dial\")\n\t}\n\n\tif c := a.getCachedClient(); c != nil {\n\t\treturn c, nil\n\t}\n\n\tcfg, err := a.RestConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbaseCacheDir := os.Getenv(\"KUBECACHEDIR\")\n\tif baseCacheDir == \"\" {\n\t\tbaseCacheDir = filepath.Join(mustHomeDir(), \".kube\", \"cache\")\n\t}\n\n\thttpCacheDir := filepath.Join(baseCacheDir, \"http\")\n\tdiscCacheDir := filepath.Join(baseCacheDir, \"discovery\", toHostDir(cfg.Host))","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/client/client.go#L473-L509","documentation":"Returned by APIClient.CachedDiscovery (internal/client/client.go:491) when connOK is false. This method builds a disk-cached discovery client (cache dir from KUBECACHEDIR or the default http cache dir) used for GVR resolution and resource mapping. Like Dial/DialLogs it is gated on the shared connection-health flag, so any earlier failed probe blocks it.","triggerScenarios":"Calling CachedDiscovery() after the connection was marked down, or before the first successful connection. Also triggered when RESTConfig() fails (bad kubeconfig) because CheckConnectivity sets connOK=false in that path.","commonSituations":"Resource listing or GVR lookups immediately after a network interruption; read-only kubeconfig with a broken certificate path; stale KUBECACHEDIR on a read-only filesystem; session resumed after cluster credentials rotated.","solutions":["Run CheckConnectivity() and only call CachedDiscovery() when it returns true","Fix the kubeconfig/credentials that made the initial probe fail, then re-init the client","Optionally set KUBECACHEDIR to a writable directory so the disk cache itself cannot fail afterwards"],"exampleFix":"// before\ndd, err := apiClient.CachedDiscovery()\n\n// after\nif apiClient.CheckConnectivity() {\n    dd, err := apiClient.CachedDiscovery()\n}","handlingStrategy":"validation","validationCode":"if !apiClient.CheckConnectivity() {\n    return nil, errors.New(\"discovery unavailable: no connection\")\n}\ndd, err := apiClient.CachedDiscovery()","typeGuard":null,"tryCatchPattern":"dd, err := apiClient.CachedDiscovery()\nif err != nil && strings.Contains(err.Error(), \"no connection to cached dial\") {\n    // reconnect, then retry once; discovery is safe to retry (idempotent)\n}","preventionTips":["Resolve GVRs once at startup via CachedDiscovery after connectivity is confirmed","Set KUBECACHEDIR to a writable path so cache writes never compound the failure","Watch for apiservice churn and re-run discovery lazily, not per keystroke"],"tags":["kubernetes","connection","discovery","cache"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}