ahmetb/kubectx · error

failed to load kubeconfig: %w

Error message

failed to load kubeconfig: %w

What it means

readonly proxy Start builds a clientcmd loading config from cfg.KubeconfigPath (explicit path) and cfg.ContextName (context override), then asks for a rest.Config via ClientConfig(). This error wraps any failure from that chain: the kubeconfig file missing or unreadable, invalid YAML, or clientcmd validation errors such as the context/cluster/user not existing or no server defined.

Source

Thrown at internal/proxy/readonly.go:68

}

// Config holds information needed to start the readonly proxy.
type Config struct {
	KubeconfigPath string
	ContextName    string
}

// Start creates and starts a readonly reverse proxy on a random localhost port.
// The proxy loads TLS/auth config from the kubeconfig and forwards only
// GET, HEAD, and OPTIONS requests (without protocol upgrades) to the real API server.
func Start(cfg Config) (*ReadonlyProxy, error) {
	loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: cfg.KubeconfigPath}
	overrides := &clientcmd.ConfigOverrides{CurrentContext: cfg.ContextName}
	clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)

	restCfg, err := clientConfig.ClientConfig()
	if err != nil {
		return nil, fmt.Errorf("failed to load kubeconfig: %w", err)
	}

	targetURL, err := url.Parse(restCfg.Host)
	if err != nil {
		return nil, fmt.Errorf("failed to parse server URL %q: %w", restCfg.Host, err)
	}

	transport, err := rest.TransportFor(restCfg)
	if err != nil {
		return nil, fmt.Errorf("failed to create transport: %w", err)
	}

	handler := NewHandler(targetURL, transport)

	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, fmt.Errorf("failed to listen: %w", err)
	}

View on GitHub (pinned to 12ad6fb22e)

Solutions

  1. Verify cfg.KubeconfigPath exists and is readable; test with kubectl --kubeconfig <path> config get-contexts
  2. Confirm cfg.ContextName matches an existing context exactly (kubectl config get-contexts); clear it to use the current context
  3. Fix validation errors clientcmd reports (missing server, missing user for the chosen context) via kubectl config set-* commands
  4. Check KUBECONFIG env var interactions if KubeconfigPath is empty — loading rules still consult the environment

Example fix

// before
cfg := proxy.Config{KubeconfigPath: "~/.kube/conf"}        // wrong path
cfg := proxy.Config{KubeconfigPath: "/home/u/.kube/config"}
Defensive patterns

Strategy: validation

Validate before calling

// Go
// Pre-check path, context existence and server before Start
if _, err := os.Stat(cfg.KubeconfigPath); err != nil {
    return fmt.Errorf("kubeconfig %s: %w", cfg.KubeconfigPath, err)
}
raw, _ := os.ReadFile(cfg.KubeconfigPath)
parsed, _ := clientcmd.Load(raw)
if cfg.ContextName != "" && !parsed.Contexts[cfg.ContextName].Cluster != true {
    // context missing
    return fmt.Errorf("context %q not found in %s", cfg.ContextName, cfg.KubeconfigPath)
}

Try / catch

p, err := proxy.Start(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "failed to load kubeconfig") {
    return fmt.Errorf("verify --kubeconfig path and --context name (kubectl config get-contexts): %w", err)
}

Prevention

When it happens

Trigger: Calling Start with cfg.KubeconfigPath pointing at a non-existent or unreadable file, cfg.ContextName naming a context absent from the kubeconfig, or a kubeconfig whose selected context lacks a valid cluster/user/server or auth data.

Common situations: Typo in --kubeconfig path or context name; context deleted from the kubeconfig after the proxy was configured; kubeconfig with stale/empty cluster entry; running the proxy on a machine without the operator's kubeconfig (CI, container).

Related errors


AI-assisted analysis of ahmetb/kubectx@12ad6fb22e (2026-09-02). Data as JSON: /api/errors/b05565156bc4f81f. Report an issue: GitHub.