GoogleContainerTools/skaffold · error

exiting dev mode because first deploy failed: %w

Error message

exiting dev mode because first deploy failed: %w

What it means

Skaffold's Dev() aborts the entire dev loop when the very first deploy attempt fails. It records a DevLoop failure event for the Deploy phase and wraps the underlying deploy error with 'exiting dev mode because first deploy failed'. Because a first deploy failure means the dev loop has nothing to watch or sync against, Skaffold stops instead of retrying.

Source

Thrown at pkg/skaffold/runner/dev.go:348

		errT := term.WaitForKeyPress()
		if errT != nil {
			return errT
		}
		// The previous Render Stage could succeed even for kubernetes resource with unknown fields, this will lead to failure in Deploy Stage
		// users need to fix the problems in their manifests, and skaffold needs to re-render them before re-running Deploy Stage in this case.
		for manifests, err = r.Render(ctx, out, r.Builds, false); err != nil; manifests, err = r.Render(ctx, out, r.Builds, false) {
			log.Entry(ctx).Warnf("Failed to Render, please fix the error and press any key to continue. %v", err)
			errT := term.WaitForKeyPress()
			if errT != nil {
				return errT
			}
		}
	}
	if err != nil {
		event.DevLoopFailedInPhase(r.devIteration, constants.Deploy, err)
		eventV2.TaskFailed(constants.DevLoop, err)
		endTrace()
		return fmt.Errorf("exiting dev mode because first deploy failed: %w", err)
	}
	r.deployManifests = manifests

	defer r.deployer.GetAccessor().Stop()

	if err := r.deployer.GetAccessor().Start(ctx, out); err != nil {
		log.Entry(ctx).Warn("Error starting resource accessor:", err)
	}
	if err := r.deployer.GetDebugger().Start(ctx); err != nil {
		log.Entry(ctx).Warn("Error starting debug container notification:", err)
	}
	// Start printing the logs after deploy is finished
	if err := r.deployer.GetLogger().Start(ctx, out); err != nil {
		return fmt.Errorf("starting logger: %w", err)
	}

	g := getTransposeGraph(artifacts)
	// Watch artifacts

View on GitHub (pinned to a1189de023)

Solutions

  1. Fix the underlying deploy error reported after the '%w' suffix (it names the real cause)
  2. Verify cluster connectivity: `kubectl cluster-info` and confirm the current context `kubectl config current-context`
  3. Confirm the built images exist in the registry the cluster pulls from
  4. Re-run `skaffold dev` once the deploy succeeds

Example fix

// before (skaffold.yaml deploy points at missing context)
deploy:
  kubectl: {defaultNamespace: prod}
// after (use an existing context/namespace)
deploy:
  kubectl:
    flags:
      kubeconfig: /home/user/.kube/config
    defaultNamespace: dev
Defensive patterns

Strategy: try-catch

Validate before calling

// before running skaffold dev
kubectl cluster-info && kubectl auth can-i create deployments --all-namespaces

Type guard

if strings.Contains(err.Error(), "exiting dev mode because first deploy failed") { /* inspect wrapped cause with errors.Unwrap */ }

Try / catch

if err := runSkaffoldDev(ctx); err != nil {
    var deployErr error
    if errors.Unwrap(err) != nil { deployErr = errors.Unwrap(err) }
    log.Printf("first deploy failed: %v", deployErr)
    return fmt.Errorf("precheck your cluster/registry: %w", deployErr)
}

Prevention

When it happens

Trigger: Calling `skaffold dev` when the initial `deploy` step returns an error: the deployer (kubectl/helm/kpt) fails to apply manifests, the cluster is unreachable, images referenced by manifests are missing, or the deployer returns a non-nil error on the first iteration.

Common situations: No kubectl context / cluster unreachable (VPN off, wrong kubeconfig); image not pushed to the registry the cluster can pull from; invalid or non-existent namespace; helm release chart errors; RBAC denials on first apply.

Related errors


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