GoogleContainerTools/skaffold · error
pod has failed
Error message
pod has failed
What it means
During pod wait, the callback inspects pod.Status.Phase and immediately fails the wait with "pod has failed" when the phase is PodFailed. It is used by deploy status checks that wait for a pod to reach Succeeded/Running and abort early on failure.
Source
Thrown at pkg/skaffold/kubernetes/wait.go:94
return func(event *watch.Event) (bool, error) {
if event.Object == nil {
return false, nil
}
pod, isPod := event.Object.(*v1.Pod)
if !isPod {
return false, nil
}
if pod.Name != podName {
return false, nil
}
switch pod.Status.Phase {
case v1.PodSucceeded:
return true, nil
case v1.PodRunning:
return false, nil
case v1.PodFailed:
return false, errors.New("pod has failed")
case v1.PodUnknown, v1.PodPending:
return false, nil
}
return false, fmt.Errorf("unknown phase: %s", pod.Status.Phase)
}
}
// WaitForPodInitialized waits until init containers have started running
func WaitForPodInitialized(ctx context.Context, pods corev1.PodInterface, podName string) error {
log.Entry(ctx).Infof("Waiting for %s to be initialized", podName)
w, err := newPodsWatcher(ctx, pods)
if err != nil {
return fmt.Errorf("initializing pod watcher: %s", err)
}
defer w.Stop()
return watchUntilTimeout(ctx, 10*time.Minute, w, func(event *watch.Event) (bool, error) {View on GitHub (pinned to a1189de023)
Solutions
- Run `kubectl describe pod <pod>` and check containerStatuses/state.exitCode for the failure reason
- Fix the container command/entrypoint or the application error causing the nonzero exit
- Check init containers and volumes (missing ConfigMaps/Secrets also fail pods) and re-run the deploy
Example fix
// before command: ["/app/run.sh"] // after command: ["/bin/sh", "-c", "chmod +x /app/run.sh && /app/run.sh"] # fix failing entrypoint
Defensive patterns
Strategy: try-catch
Validate before calling
// before waiting, verify pod spec sanity
if pod.Spec.RestartPolicy == v1.RestartPolicyNever && isJobLike(pod) { /* failure = non-zero exit, handle explicitly */ } Type guard
func podFailed(pod *v1.Pod) bool { return pod.Status.Phase == v1.PodFailed } Try / catch
done, err := waitFn(pod)
if err != nil && podFailed(pod) {
reason := firstContainerTerminationReason(pod) // e.g. Error, OOMKilled
return fmt.Errorf("pod %s failed (reason=%s): %w", pod.Name, reason, err)
} Prevention
- Set container commands/entrypoints that cannot exit immediately (chmod scripts, correct binary paths)
- Check init containers and referenced ConfigMaps/Secrets exist
- Keep restartPolicy consistent with the job intent
When it happens
Trigger: Waiting on a pod whose status transitions to v1.PodFailed (container exited nonzero, failed init container, failed scheduler/eviction reporting Failure phase).
Common situations: Test pods or Jobs whose containers exit with a nonzero code; nodes evicting pods; images with bad entrypoints so the main container immediately dies.
Related errors
- STATUSCHECK_POD_INITIALIZING
- waiting for init container %s to complete
- STATUSCHECK_UNKNOWN
- STATUSCHECK_CONTAINER_TERMINATED
- STATUSCHECK_UNKNOWN_UNSCHEDULABLE
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/84f03ad165b77dfb.
Report an issue: GitHub.