{"record":{"id":"ac967871510648a2","repo":"GoogleContainerTools/skaffold","slug":"waiting-for-init-container-s-to-complete","errorCode":null,"errorMessage":"waiting for init container %s to complete","messagePattern":"waiting for init container (.+?) to complete","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/diag/validator/validator.go","lineNumber":156,"sourceCode":"\t\tsc, err := getUntoleratedTaints(c.Reason, c.Message)\n\t\treturn sc, nil, err\n\t}\n\t// we can check the container status if the pod has been scheduled successfully. This can be determined by having the event\n\t// PodScheduled with status True, or a ContainerReady or PodReady event with status False.\n\tif isPodScheduledButNotReady(pod) {\n\t\tlog.Entry(context.TODO()).Debugf(\"Pod %q scheduled but not ready: checking container statuses\", pod.Name)\n\t\t// TODO(dgageot): Add EphemeralContainerStatuses\n\t\tcs := append(pod.Status.InitContainerStatuses, pod.Status.ContainerStatuses...)\n\t\t// See https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-states\n\t\tstatusCode, logs, err := getContainerStatus(pod, cs)\n\t\tif statusCode == proto.StatusCode_STATUSCHECK_POD_INITIALIZING {\n\t\t\t// Determine if an init container is still running and fetch the init logs.\n\t\t\tfor _, c := range pod.Status.InitContainerStatuses {\n\t\t\t\tif c.State.Waiting != nil {\n\t\t\t\t\treturn statusCode, []string{}, fmt.Errorf(\"waiting for init container %s to start\", c.Name)\n\t\t\t\t} else if c.State.Running != nil {\n\t\t\t\t\tsc, l := getPodLogs(pod, c.Name, statusCode)\n\t\t\t\t\treturn sc, l, fmt.Errorf(\"waiting for init container %s to complete\", c.Name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn statusCode, logs, err\n\t}\n\n\tif c, ok := isPodStatusUnknown(pod); ok {\n\t\tlog.Entry(context.TODO()).Debugf(\"Pod %q condition status of type %s is unknown\", pod.Name, c.Type)\n\t\treturn proto.StatusCode_STATUSCHECK_UNKNOWN, nil, errors.New(c.Message)\n\t}\n\n\tlog.Entry(context.TODO()).Debugf(\"Unable to determine current service state of pod %q\", pod.Name)\n\treturn proto.StatusCode_STATUSCHECK_UNKNOWN, nil, fmt.Errorf(\"unable to determine current service state of pod %q\", pod.Name)\n}\n\nfunc isPodReady(pod *v1.Pod) bool {\n\tfor _, c := range pod.Status.Conditions {\n\t\tif c.Type == v1.PodReady && c.Status == v1.ConditionTrue {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/diag/validator/validator.go#L138-L174","documentation":"This variant of the pod-initializing error (code STATUSCHECK_POD_INITIALIZING) means an init container has started and is Running but has not finished, so the main containers cannot begin. Skaffold fetches and returns the init container logs alongside the message to help diagnose why it is taking long.","triggerScenarios":"getPodStatus finds an init container whose State.Running is non-nil; it calls getPodLogs for that container and returns 'waiting for init container <name> to complete'.","commonSituations":"Long-running init scripts (migrations, waits-for-dependency loops); init container looping on 'wait for DB/queue' checks that never succeed; very slow image or volume mounts; init script bug causing an infinite loop.","solutions":["Read the returned init logs (or kubectl logs <pod> -c <init-container> -f) to see which step the init container is blocked on.","If the init container waits on a dependency, fix that dependency (DB up, endpoint reachable, DNS resolving).","Shorten or add a timeout/failure exit to the init script so the pod fails fast instead of hanging.","Split heavy work out of initContainers into the app or a Job if it legitimately takes minutes."],"exampleFix":"// before\n// command: [\"sh\",\"-c\",\"until nc -z db 5432; do sleep 1; done\"] // loops forever if DNS broken\n// after\n// command: [\"sh\",\"-c\",\"timeout 60 sh -c 'until nc -z db 5432; do sleep 1; done' || exit 1\"]","handlingStrategy":"retry","validationCode":"for _, ic := range pod.Status.InitContainerStatuses { if ic.State.Running != nil { tail, _ := getPodLogs(pod, ic.Name); fmt.Printf(\"init %s running, logs: %s\", ic.Name, tail) } }","typeGuard":"func initContainersDone(pod *v1.Pod) bool { for _, c := range pod.Status.InitContainerStatuses { if c.State.Terminated == nil || c.State.Terminated.ExitCode != 0 { return false } } return len(pod.Status.InitContainerStatuses) > 0 }","tryCatchPattern":"status, logs, err := getPodStatus(pod); if errors.Is(err, errInitRunning) { select { case <-time.After(5 * time.Second): goto retry\n\tcase <-ctx.Done(): return ctx.Err() } }","preventionTips":["Add hard timeouts to init scripts (timeout N or deadline exit)","Log progress inside init containers so stuck steps are obvious","Poll with backoff instead of tight loops when waiting on init","Move minutes-long work out of initContainers into Jobs"],"tags":["kubernetes","pod","init-container","status-check"],"backgroundTag":"pod-stuck-initializing","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"}