{"record":{"id":"60a88a5552651a21","repo":"GoogleContainerTools/skaffold","slug":"statuscheck-container-restarting","errorCode":"STATUSCHECK_CONTAINER_RESTARTING","errorMessage":"container %s is backing off waiting to restart","messagePattern":"container (.+?) is backing off waiting to restart","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/diag/validator/validator.go","lineNumber":369,"sourceCode":"\t\t\treturn p.ae.Message\n\t\t}\n\t}\n\treturn fmt.Sprintf(actionableMessage, p.namespace, p.name)\n}\n\nfunc extractErrorMessageFromWaitingContainerStatus(po *v1.Pod, c v1.ContainerStatus) (proto.StatusCode, []string, error) {\n\t// Extract meaning full error out of container statuses.\n\tswitch c.State.Waiting.Reason {\n\tcase podInitializing:\n\t\t// container is waiting to run. This could be because one of the init containers is\n\t\t// still not completed\n\t\treturn proto.StatusCode_STATUSCHECK_POD_INITIALIZING, nil, nil\n\tcase containerCreating:\n\t\treturn proto.StatusCode_STATUSCHECK_CONTAINER_CREATING, nil, fmt.Errorf(\"creating container %s\", c.Name)\n\tcase crashLoopBackOff:\n\t\t// TODO, in case of container restarting, return the original failure reason due to which container failed.\n\t\tsc, l := getPodLogs(po, c.Name, proto.StatusCode_STATUSCHECK_CONTAINER_RESTARTING)\n\t\treturn sc, l, fmt.Errorf(\"container %s is backing off waiting to restart\", c.Name)\n\tcase ImagePullErr, ImagePullBackOff, ErrImagePullBackOff:\n\t\treturn proto.StatusCode_STATUSCHECK_IMAGE_PULL_ERR, nil, fmt.Errorf(\"container %s is waiting to start: %s can't be pulled\", c.Name, c.Image)\n\tcase runContainerError:\n\t\tmatch := runContainerRe.FindStringSubmatch(c.State.Waiting.Message)\n\t\tif len(match) != 0 {\n\t\t\treturn proto.StatusCode_STATUSCHECK_RUN_CONTAINER_ERR, nil, fmt.Errorf(\"container %s in error: %s\", c.Name, trimSpace(match[3]))\n\t\t}\n\t}\n\tlog.Entry(context.TODO()).Debugf(\"Unknown waiting reason for container %q: %v\", c.Name, c.State)\n\treturn proto.StatusCode_STATUSCHECK_CONTAINER_WAITING_UNKNOWN, nil, fmt.Errorf(\"container %s in error: %v\", c.Name, c.State.Waiting)\n}\n\nfunc newPodStatus(n string, ns string, p string) *podStatus {\n\treturn &podStatus{\n\t\tname:      n,\n\t\tnamespace: ns,\n\t\tphase:     p,\n\t\tae: proto.ActionableErr{","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/diag/validator/validator.go#L351-L387","documentation":"Raised when a container's Waiting state has reason CrashLoopBackOff (code STATUSCHECK_CONTAINER_RESTARTING): the container keeps crashing and kubelet is backing off before restarting it. Skaffold fetches logs from the last attempt so the original failure is visible.","triggerScenarios":"extractErrorMessageFromWaitingContainerStatus matches crashLoopBackOff in the Waiting reason, calls getPodLogs, and returns 'container <name> is backing off waiting to restart'; reached from getContainerStatus/getPodStatus.","commonSituations":"App crashes at startup (bad config, missing env var/secret, unreachable dependency), failing liveness probes restarting a healthy-but-slow app, wrong command/args, port conflicts, exit-on-error scripts.","solutions":["Read the captured logs (or kubectl logs <pod> --previous -c <container>) to find the original crash cause and fix it.","Check liveness/readiness probes: overly aggressive initialDelaySeconds/periodSeconds can kill slow-starting apps; tune them.","Verify required env vars, secrets, config maps, and dependency endpoints are present and reachable.","kubectl describe pod to confirm restartCount and reason, then fix the command/args or image entrypoint."],"exampleFix":"// before: liveness probe kills slow starter\n// livenessProbe: {httpGet: {path: /healthz, port: 8080}, initialDelaySeconds: 1}\n// after\n// livenessProbe: {httpGet: {path: /healthz, port: 8080}, initialDelaySeconds: 30, failureThreshold: 5}","handlingStrategy":"try-catch","validationCode":"if cs.State.Waiting != nil && cs.State.Waiting.Reason == \"CrashLoopBackOff\" { prev, _ := client.CoreV1().Pods(ns).GetLogs(pod.Name, &v1.PodLogOptions{Container: cs.Name, Previous: true}).Stream(ctx); dump(prev) }","typeGuard":"func isCrashLooping(cs v1.ContainerStatus) bool { return cs.State.Waiting != nil && cs.State.Waiting.Reason == \"CrashLoopBackOff\" }","tryCatchPattern":"sc, logs, err := getContainerStatus(pod, cs); if sc == proto.StatusCode_STATUSCHECK_CONTAINER_RESTARTING { return fmt.Errorf(\"crash loop, last logs:\\n%s\", strings.Join(logs, \"\\n\")) }","preventionTips":["Make apps log the fatal cause before exiting non-zero","Gate deploys on local smoke tests of the same image/command","Set sensible liveness probe initialDelay/failureThreshold","Validate required env/secrets/configmaps before rollout (use a startup check)"],"tags":["kubernetes","pod","crashloopbackoff","container-restart"],"backgroundTag":"crashloopbackoff","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}