{"record":{"id":"6237e0a91d834ff6","repo":"GoogleContainerTools/skaffold","slug":"failed-to-execute-container-s-hook-d-for-artifac","errorCode":null,"errorMessage":"failed to execute container %s hook %d for artifact %q: %w","messagePattern":"failed to execute container (.+?) hook (.+?) for artifact %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/hooks/sync.go","lineNumber":97,"sourceCode":"\t\toutput.Default.Fprintf(out, \"Starting %s hooks for artifact %q...\\n\", phase, r.imageName)\n\t}\n\tenv := r.getEnv()\n\tfor i, h := range hooks {\n\t\tif h.HostHook != nil {\n\t\t\thook := hostHook{*h.HostHook, env}\n\t\t\tif err := hook.run(ctx, nil, out); err != nil && !errors.Is(err, &Skip{}) {\n\t\t\t\treturn fmt.Errorf(\"failed to execute host %s hook %d for artifact %q: %w\", phase, i+1, r.imageName, err)\n\t\t\t}\n\t\t} else if h.ContainerHook != nil {\n\t\t\thook := containerHook{\n\t\t\t\tcfg:        *h.ContainerHook,\n\t\t\t\tcli:        r.cli,\n\t\t\t\tselector:   runningImageSelector(r.imageRef),\n\t\t\t\tnamespaces: r.namespaces,\n\t\t\t\tformatter:  r.formatter,\n\t\t\t}\n\t\t\tif err := hook.run(ctx, out); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to execute container %s hook %d for artifact %q: %w\", phase, i+1, r.imageName, err)\n\t\t\t}\n\t\t}\n\t}\n\tif len(hooks) > 0 {\n\t\toutput.Default.Fprintf(out, \"Completed %s hooks for artifact %q\\n\", phase, r.imageName)\n\t}\n\treturn nil\n}\n","sourceCodeStart":79,"sourceCodeEnd":106,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/hooks/sync.go#L79-L106","documentation":"Skaffold also supports container hooks — commands executed inside the running artifact's container during sync. If such a hook's run() returns any error (Skip handling doesn't apply here), run wraps it with the phase, 1-based hook index, artifact image name, and underlying cause, aborting the sync.","triggerScenarios":"A containerHook command fails inside the running container while RunPreHooks/RunPostHooks process sync hooks for the artifact: command not found in the container image, non-zero exit, kubectl exec/transport error reaching the pod, or the container/pod not running in any of the target namespaces.","commonSituations":"Command present on host but absent in the slim container image; hook requires a shell not installed (distroless images); pod not yet ready so exec fails; RBAC/namespace mismatch preventing exec.","solutions":["Verify the command exists inside the image (docker run <img> <cmd>) and add it to the Dockerfile if missing","Check the wrapped error: if it's an exec/pod error, ensure the pod is running and the namespaces list matches where the workload runs","Use sh -c wrapping and correct quoting; for distroless images switch to a host hook or copy a shell in","Run with --verbosity=debug to see the exact exec command and pod it targeted"],"exampleFix":"// before (skaffold.yaml, distroless image)\nsync:\n  hooks:\n    after:\n      - container:\n          command: [\"sh\", \"-c\", \"touch /tmp/reload\"]\n// after (use a host hook instead)\nsync:\n  hooks:\n    after:\n      - host:\n          command: [\"kubectl\", \"exec\", \"deploy/my-app\", \"--\", \"kill\", \"-HUP\", \"1\"]","handlingStrategy":"retry","validationCode":"// ensure the target pods are running and the command exists in the image:\nkubectl get pods -n <ns> -l <selector> --field-selector=status.phase=Running\ndocker run --rm <image> <hook_cmd> --help  # proves the binary is in the image","typeGuard":null,"tryCatchPattern":"if err := syncRunner.RunPostHooks(ctx, out); err != nil {\n    if strings.Contains(err.Error(), \"failed to execute container\") {\n        // often a transient exec/pod-readiness issue: retry once after a short wait\n        time.Sleep(2 * time.Second)\n        return syncRunner.RunPostHooks(ctx, out)\n    }\n    return err\n}","preventionTips":["Bake hook commands and shells into the image, or use host hooks for distroless images","Wait for pod readiness before dev/sync loops; verify namespaces match the deployed workload","Check RBAC allows exec into pods in target namespaces"],"tags":["sync","hooks","container","kubernetes","skaffold"],"backgroundTag":"container-hook-exec-failed","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"}