GoogleContainerTools/skaffold · warning

STATUSCHECK_CONTAINER_WAITING_UNKNOWN

STATUSCHECK_CONTAINER_WAITING_UNKNOWN

Error message

container %s in error: %v

What it means

Fallback branch of extractErrorMessageFromWaitingContainerStatus: the container is Waiting but Skaffold does not recognize the waiting reason (it did not match CrashLoopBackOff, ImagePullBackOff, or the run-container regex). It returns STATUSCHECK_CONTAINER_WAITING_UNKNOWN and embeds the whole Waiting state struct for debugging.

Source

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

		// container is waiting to run. This could be because one of the init containers is
		// still not completed
		return proto.StatusCode_STATUSCHECK_POD_INITIALIZING, nil, nil
	case containerCreating:
		return proto.StatusCode_STATUSCHECK_CONTAINER_CREATING, nil, fmt.Errorf("creating container %s", c.Name)
	case crashLoopBackOff:
		// TODO, in case of container restarting, return the original failure reason due to which container failed.
		sc, l := getPodLogs(po, c.Name, proto.StatusCode_STATUSCHECK_CONTAINER_RESTARTING)
		return sc, l, fmt.Errorf("container %s is backing off waiting to restart", c.Name)
	case ImagePullErr, ImagePullBackOff, ErrImagePullBackOff:
		return proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, nil, fmt.Errorf("container %s is waiting to start: %s can't be pulled", c.Name, c.Image)
	case runContainerError:
		match := runContainerRe.FindStringSubmatch(c.State.Waiting.Message)
		if len(match) != 0 {
			return proto.StatusCode_STATUSCHECK_RUN_CONTAINER_ERR, nil, fmt.Errorf("container %s in error: %s", c.Name, trimSpace(match[3]))
		}
	}
	log.Entry(context.TODO()).Debugf("Unknown waiting reason for container %q: %v", c.Name, c.State)
	return proto.StatusCode_STATUSCHECK_CONTAINER_WAITING_UNKNOWN, nil, fmt.Errorf("container %s in error: %v", c.Name, c.State.Waiting)
}

func newPodStatus(n string, ns string, p string) *podStatus {
	return &podStatus{
		name:      n,
		namespace: ns,
		phase:     p,
		ae: proto.ActionableErr{
			ErrCode: proto.StatusCode_STATUSCHECK_SUCCESS,
		},
	}
}

func trimSpace(msg string) string {
	return strings.Trim(msg, " ")
}

func getPodLogs(po *v1.Pod, c string, sc proto.StatusCode) (proto.StatusCode, []string) {

View on GitHub (pinned to a1189de023)

Solutions

  1. Inspect the embedded Waiting state in the error and the pod with kubectl describe pod / kubectl events to find the actual blocking reason.
  2. Ensure dependent resources (PVC, ConfigMap, Secret, CNI) exist and are bound before running the skaffold health check.
  3. If the reason is a legitimate new Kubernetes waiting reason, update the validator's known-reason switch in pkg/diag/validator/validator.go to map it.

Example fix

// before
c.name: container stuck Waiting, unknown reason
// after
kubectl -n <ns> describe pod <pod>  # then create the missing ConfigMap/PVC the pod references
Defensive patterns

Strategy: validation

Validate before calling

// Ensure referenced resources exist before deploying
kubectl -n <ns> get configmap,secret,pvc
kubectl -n <ns> get events --field-selector type=Warning

Try / catch

try {
  await skaffold.run(...);
} catch (e) {
  if (String(e).includes('CONTAINER_WAITING_UNKNOWN')) {
    // capture pod state for diagnosis and retry after infra is fixed
    console.error('Pod stuck Waiting with unknown reason; run kubectl describe pod');
  }
  throw e;
}

Prevention

When it happens

Trigger: getContainerStatus finds a pod container in Waiting state whose Reason is none of the known constants (or Message does not match runContainerRe), e.g. a newly introduced kubelet reason or ContainerCreating timeouts.

Common situations: Container stuck in ContainerCreating because a PVC or ConfigMap is not bound; cluster upgraded to a Kubernetes version emitting a new waiting reason; CNI plugin slow so the container never leaves Waiting.

Related errors


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