GoogleContainerTools/skaffold · error

getting k8s client: %w

Error message

getting k8s client: %w

What it means

The k8s log watcher's Start method obtains a Kubernetes client via client.Client(kubeContext) before watching pods across namespaces; failure is wrapped as 'getting k8s client: %w'. This means a REST config could not be built for the given kube-context — bad kubeconfig, unknown context, or missing credentials.

Source

Thrown at pkg/skaffold/kubernetes/watcher.go:84

	w.receivers[receiver] = false
	w.receiverLock.Unlock()
}

func (w *podWatcher) Start(ctx context.Context, kubeContext string, namespaces []string) (func(), error) {
	if len(w.receivers) == 0 {
		return func() {}, errors.New("no receiver was registered")
	}

	var watchers []watch.Interface
	stopWatchers := func() {
		for _, w := range watchers {
			w.Stop()
		}
	}

	kubeclient, err := client.Client(kubeContext)
	if err != nil {
		return func() {}, fmt.Errorf("getting k8s client: %w", err)
	}

	var forever int64 = 3600 * 24 * 365 * 100

	for _, ns := range namespaces {
		watcher, err := kubeclient.CoreV1().Pods(ns).Watch(context.Background(), metav1.ListOptions{
			TimeoutSeconds: &forever,
		})
		if err != nil {
			stopWatchers()
			return func() {}, fmt.Errorf("initializing pod watcher for %q: %w", ns, err)
		}

		watchers = append(watchers, watcher)
		go func() {
			l := log.Entry(ctx)
			defer l.Tracef("podWatcher: cease waiting")
			l.Tracef("podWatcher: waiting")

View on GitHub (pinned to a1189de023)

Solutions

  1. List valid contexts with `kubectl config get-contexts` and pass an existing one (or drop --kube-context)
  2. Check KUBECONFIG points at the intended, well-formed kubeconfig file
  3. Recreate/reconnect the cluster (kind create cluster, minikube start) if it was deleted; refresh cloud credentials
  4. Run inside the cluster with proper service-account credentials if in-cluster config is expected

Example fix

// before
skaffold dev --kube-context old-cluster
// after
skaffold dev --kube-context minikube
Defensive patterns

Strategy: validation

Validate before calling

// verify the kube-context resolves before starting the watcher
func ensureContext(name string) error {
    if name == "" {
        return nil // default context
    }
    cfg, err := clientcmd.LoadFromFile(os.Getenv("KUBECONFIG"))
    if err != nil {
        return err
    }
    if _, ok := cfg.Contexts[name]; !ok {
        return fmt.Errorf("kube-context %q not found; have: %v", name, contextNames(cfg))
    }
    return nil
}

Try / catch

cleanup, err := watcher.Start(ctx, namespaces, kubeContext)
if err != nil {
    var ce *clientcmderr.Error
    if errors.As(err, &ce) || strings.Contains(err.Error(), "getting k8s client") {
        return fmt.Errorf("fix kubeconfig/context (kubectl config get-contexts): %w", err)
    }
    return err
}
defer cleanup()

Prevention

When it happens

Trigger: Starting the pod log watcher (e.g. `skaffold dev`/`run` with log streaming) when client.Client(kubeContext) fails: the kube-context name doesn't exist in kubeconfig, the kubeconfig file is malformed/missing, or in-cluster credentials are absent.

Common situations: Wrong kube-context passed via --kube-context; KUBECONFIG pointing at a stale file; minikube/kind cluster deleted so the context's server is gone; running outside the cluster without a kubeconfig when an in-cluster config was expected.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/3ecd385cf5b01764. Report an issue: GitHub.