{"record":{"id":"37f1167af177f1fd","repo":"ahmetb/kubectx","slug":"failed-to-create-transport-w","errorCode":null,"errorMessage":"failed to create transport: %w","messagePattern":"failed to create transport: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/proxy/readonly.go","lineNumber":78,"sourceCode":"// GET, HEAD, and OPTIONS requests (without protocol upgrades) to the real API server.\nfunc Start(cfg Config) (*ReadonlyProxy, error) {\n\tloadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: cfg.KubeconfigPath}\n\toverrides := &clientcmd.ConfigOverrides{CurrentContext: cfg.ContextName}\n\tclientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)\n\n\trestCfg, err := clientConfig.ClientConfig()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load kubeconfig: %w\", err)\n\t}\n\n\ttargetURL, err := url.Parse(restCfg.Host)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse server URL %q: %w\", restCfg.Host, err)\n\t}\n\n\ttransport, err := rest.TransportFor(restCfg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create transport: %w\", err)\n\t}\n\n\thandler := NewHandler(targetURL, transport)\n\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to listen: %w\", err)\n\t}\n\n\tsrv := &http.Server{Handler: handler}\n\tgo srv.Serve(listener)\n\n\tdebugLog.Printf(\"started on %s, proxying to %s\", listener.Addr(), targetURL)\n\n\treturn &ReadonlyProxy{\n\t\tserver:   srv,\n\t\tlistener: listener,\n\t}, nil","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/ahmetb/kubectx/blob/12ad6fb22e8c546ee2b54e7de38aa51c906832f7/internal/proxy/readonly.go#L60-L96","documentation":"This error is returned by proxy.Start when rest.TransportFor(restCfg) fails to build an http.RoundTripper from the loaded kubeconfig REST config. TransportFor validates and materializes the TLS, client-cert, bearer-token, exec-credential, and proxy settings from the rest.Config, so any invalid or unusable credential material in the kubeconfig surfaces here. It is a wrapping error: the underlying client-go cause (e.g. x509 parse failure) is embedded via %w.","triggerScenarios":"rest.TransportFor fails when the kubeconfig context referenced by Config.ContextName points to a cluster/user with malformed TLS data (bad certificate or key PEM), a client cert/key pair that does not match, an exec credential plugin that is missing, not executable, or exits non-zero, or an invalid CA file path / proxy URL.","commonSituations":"Kubeconfig generated by an older cluster bootstrap with expired or corrupt client certificates; KUBECONFIG pointing at a context whose user uses an exec plugin (aws eks get-token, gke-gcloud-auth-plugin) that is not installed or not on PATH; a certificate-authority path moved or deleted; hand-edited kubeconfig with base64 padding mistakes.","solutions":["Run the exec/auth plugin manually (e.g. `aws eks get-token --cluster-name ...` or `gke-gcloud-auth-plugin`) to see the underlying cause and install/repair it if missing","Inspect the current context's user/cluster in the kubeconfig (`kubectl config view --raw`) and fix or regenerate the certificate/key/CA data (`aws eks update-kubeconfig`, `gcloud container clusters get-credentials`, etc.)","Check that certificate file paths in the kubeconfig exist and that cert and key match (compare modulus/fingerprints)","Switch KUBECONFIG or --context to a known-good context to isolate whether the problem is credential material","Set KUBECTX_DEBUG=1 and re-run; the wrapped client-go error text names the exact field that failed"],"exampleFix":"// before (exec plugin missing)\nusers:\n- name: my-user\n  user:\n    exec:\n      command: gke-gcloud-auth-plugin  # not installed\n// after\n// install the plugin first:\n//   gcloud components install gke-gcloud-auth-plugin\nusers:\n- name: my-user\n  user:\n    exec:\n      command: /usr/local/bin/gke-gcloud-auth-plugin\n      apiVersion: client.authentication.k8s.io/v1beta1","handlingStrategy":"try-catch","validationCode":"// Go: validate kubeconfig credential material before calling proxy.Start\nfunc validateKubeconfig(path, ctxName string) error {\n\tloadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: path}\n\toverrides := &clientcmd.ConfigOverrides{CurrentContext: ctxName}\n\tcc := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)\n\trestCfg, err := cc.ClientConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kubeconfig load: %w\", err)\n\t}\n\tif restCfg.Host == \"\" {\n\t\treturn fmt.Errorf(\"context %q has no server\", ctxName)\n\t}\n\tif restCfg.ExecProvider != nil {\n\t\tif _, err := exec.LookPath(restCfg.ExecProvider.Command); err != nil {\n\t\t\treturn fmt.Errorf(\"exec plugin %q not installed\", restCfg.ExecProvider.Command)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isTransportConfigError(err error) bool {\n\t// narrow the wrapped cause before deciding how to react\n\tvar ce *x509.CertificateInvalidError\n\tif errors.As(err, &ce) {\n\t\treturn true // expired/untrusted cert: fix kubeconfig, no retry\n\t}\n\treturn strings.Contains(err.Error(), \"failed to create transport\")\n}","tryCatchPattern":"p, err := proxy.Start(cfg)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to create transport\") {\n\t\tvar pe *exec.Error\n\t\tif errors.As(err, &pe) {\n\t\t\treturn fmt.Errorf(\"auth plugin %s not found: %w\", pe.Name, err)\n\t\t}\n\t\treturn fmt.Errorf(\"bad credential material in kubeconfig: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Regenerate kubeconfig credentials with the cloud CLI (aws eks update-kubeconfig, gcloud container clusters get-credentials) instead of hand-editing base64 cert blocks","Keep auth exec plugins (aws, gcloud, azure) installed and on PATH; verify with a plain `kubectl get nodes` before invoking the library","Run `kubectl config view --raw --minify` to confirm the active context has a valid server, CA, and client credential","Check cert/key/CA file paths are absolute and readable by the process","Use `errors.As` on the wrapped error to distinguish exec-plugin failures from TLS failures"],"tags":["go","kubernetes","tls","kubeconfig","transport"],"backgroundTag":"kubeconfig-transport-error","analyzedSha":"12ad6fb22e8c546ee2b54e7de38aa51c906832f7","analyzedAt":"2026-09-02T12:23:10.107Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}