{"record":{"id":"a6118ac8846d04b1","repo":"derailed/k9s","slug":"diallogs-no-connection-to-dial","errorCode":null,"errorMessage":"dialLogs - no connection to dial","messagePattern":"dialLogs - no connection to dial","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/client.go","lineNumber":441,"sourceCode":"\nfunc (a *APIClient) setClient(k kubernetes.Interface) {\n\ta.mx.Lock()\n\tdefer a.mx.Unlock()\n\n\ta.client = k\n}\n\nfunc (a *APIClient) getClient() kubernetes.Interface {\n\ta.mx.RLock()\n\tdefer a.mx.RUnlock()\n\n\treturn a.client\n}\n\n// DialLogs returns a handle to api server for logs.\nfunc (a *APIClient) DialLogs() (kubernetes.Interface, error) {\n\tif !a.getConnOK() {\n\t\treturn nil, errors.New(\"dialLogs - no connection to dial\")\n\t}\n\tif clt := a.getLogClient(); clt != nil {\n\t\treturn clt, nil\n\t}\n\n\tcfg, err := a.RestConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Timeout = 0\n\tc, err := kubernetes.NewForConfig(cfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ta.setLogClient(c)\n\n\treturn a.getLogClient(), nil\n}","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/client/client.go#L423-L459","documentation":"Returned by APIClient.DialLogs (internal/client/client.go:441) when getConnOK() is false. DialLogs lazily builds a dedicated clientset for log streaming (it zeroes cfg.Timeout so streaming is never cut off), but only after the connection health flag is verified. The guard mirrors Dial(): a failed connectivity check poisons every dial path until reconnection.","triggerScenarios":"Invoking DialLogs() after CheckConnectivity() marked the connection down (ServerVersion probe failure, RESTConfig error, panic in the check), or before any successful connection was established in this process.","commonSituations":"Viewing pod logs right after the laptop wakes from sleep and the API server is temporarily unreachable; API server restart; proxy/load-balancer dropped the session; using a client that was constructed but never connected.","solutions":["Call CheckConnectivity() and reconnect until it returns true, then retry DialLogs","Fix the underlying connectivity (VPN, kubeconfig server URL, exec-credential expiry) and re-run the connection check","Ensure the code does not cache a failed APIClient across context switches — recreate it after switching clusters"],"exampleFix":"// before\nconn, err := apiClient.DialLogs()\n\n// after\nif apiClient.CheckConnectivity() {\n    conn, err := apiClient.DialLogs()\n}\n// otherwise report 'no API server connection' to the user and stop","handlingStrategy":"validation","validationCode":"if !apiClient.CheckConnectivity() {\n    return nil, errors.New(\"logs unavailable: api server down\")\n}\nconn, err := apiClient.DialLogs()","typeGuard":null,"tryCatchPattern":"conn, err := apiClient.DialLogs()\nif err != nil {\n    if strings.Contains(err.Error(), \"no connection to dial\") {\n        ui.NotifyError(\"Connection lost — reconnecting\")\n        if apiClient.CheckConnectivity() {\n            conn, err = apiClient.DialLogs() // one retry after reconnect\n        }\n    }\n}","preventionTips":["Check connectivity before opening log views","Cache DialLogs' client is already done by the APIClient — avoid caching nil results yourself","Handle laptop sleep/VPN changes by re-validating the connection when the UI regains focus"],"tags":["kubernetes","connection","logs","clientset"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}