GoogleContainerTools/skaffold · error

STATUSCHECK_CONTAINER_TERMINATED

STATUSCHECK_CONTAINER_TERMINATED

Error message

container %s terminated with exit code %d

What it means

This error (code STATUSCHECK_CONTAINER_TERMINATED) is raised when a container in the pod has terminated with a non-zero exit code. Skaffold also captures the container logs and returns them so the failure reason can be diagnosed.

Source

Thrown at pkg/diag/validator/validator.go:222

func isPodStatusUnknown(pod *v1.Pod) (v1.PodCondition, bool) {
	for _, c := range pod.Status.Conditions {
		if c.Status == v1.ConditionUnknown {
			return c, true
		}
	}
	return v1.PodCondition{}, false
}

func getContainerStatus(po *v1.Pod, cs []v1.ContainerStatus) (proto.StatusCode, []string, error) {
	// See https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-states
	for _, c := range cs {
		switch {
		case c.State.Waiting != nil:
			return extractErrorMessageFromWaitingContainerStatus(po, c)
		case c.State.Terminated != nil && c.State.Terminated.ExitCode != 0:
			sc, l := getPodLogs(po, c.Name, proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED)
			return sc, l, fmt.Errorf("container %s terminated with exit code %d", c.Name, c.State.Terminated.ExitCode)
		}
	}
	// No waiting or terminated containers, pod should be in good health.
	return proto.StatusCode_STATUSCHECK_SUCCESS, nil, nil
}

func getUntoleratedTaints(reason string, message string) (proto.StatusCode, error) {
	matches := taintsRe.FindAllStringSubmatch(message, -1)
	errCode := proto.StatusCode_STATUSCHECK_UNKNOWN_UNSCHEDULABLE
	if len(matches) == 0 {
		return errCode, fmt.Errorf("%s: %s", reason, message)
	}
	messages := make([]string, len(matches))
	// TODO: Add actionable item to fix these errors.
	for i, m := range matches {
		if len(m) < 2 {
			continue
		}

View on GitHub (pinned to a1189de023)

Solutions

  1. Read the captured logs (or kubectl logs <pod> -c <container> --previous) to find the crash stack and exit-code cause.
  2. Fix the application bug or misconfiguration the stack trace points to.
  3. Check kubectl describe pod for OOMKilled / reason, and raise memory limits if exit code 137.
  4. Verify the container command/args match the image's expected entrypoint.

Example fix

// before: wrong flag causes immediate exit
// args: ["--port", "8080x"]
// after
// args: ["--port", "8080"]
Defensive patterns

Strategy: try-catch

Validate before calling

for _, cs := range pod.Status.ContainerStatuses { if cs.State.Terminated != nil && cs.State.Terminated.ExitCode != 0 { return fmt.Errorf("%s exited %d: %s", cs.Name, cs.State.Terminated.ExitCode, cs.State.Terminated.Message) } }

Type guard

func hasTerminatedContainer(pod *v1.Pod) (*v1.ContainerStatus, bool) { for i, c := range pod.Status.ContainerStatuses { if c.State.Terminated != nil && c.State.Terminated.ExitCode != 0 { return &pod.Status.ContainerStatuses[i], true } } return nil, false }

Try / catch

sc, logs, err := getContainerStatus(pod, statuses); if sc == proto.StatusCode_STATUSCHECK_CONTAINER_TERMINATED { return fmt.Errorf("container failed, logs:\n%s", strings.Join(logs, "\n")) }

Prevention

When it happens

Trigger: getContainerStatus iterates pod container statuses and hits a case where c.State.Terminated != nil && c.State.Terminated.ExitCode != 0; it fetches logs via getPodLogs and returns 'container <name> terminated with exit code <N>'.

Common situations: Application crash (panic, unhandled exception), bad entrypoint/command arguments, missing config or env vars causing immediate exit, OOM-killed processes (exit 137), failed readiness-relevant startup logic.

Related errors


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