goreleaser/goreleaser · error
pre hook failed: %w
Error message
pre hook failed: %w
What it means
The dockers_v2 pipe runs user-defined pre-build hooks (shell commands) before `docker buildx build`. This error wraps any failure returned by runHook for the `hooks.pre` list, aborting the image build. It indicates a pre hook command exited non-zero or could not run.
Source
Thrown at internal/pipe/docker/v2/docker.go:247
}
log.WithField("id", d.ID).
WithField("images", strings.Join(da.images, "\n")).
Info("creating images")
wd, err := makeContext(d, contextArtifacts(ctx, d), da.dockerfile)
if err != nil {
return err
}
defer os.RemoveAll(wd)
hookFields := tmpl.Fields{
keyImages: da.images,
keyDockerfile: da.dockerfile,
keyContextDir: wd,
}
if err := runHook(ctx, hookFields, d.Hooks.Pre); err != nil {
return fmt.Errorf("pre hook failed: %w", err)
}
digest, err := doBuild(ctx, d, wd, da.args)
if err != nil {
return err
}
hookFields[keyDigest] = digest
if err := runHook(ctx, hookFields, d.Hooks.Post); err != nil {
return fmt.Errorf("post hook failed: %w", err)
}
log.WithField("id", d.ID).
WithField("images", strings.Join(da.images, "\n")).
WithField("digest", digest).
Info("created images")
for _, img := range da.images {View on GitHub (pinned to f5edd73956)
Solutions
- Run the failing hook command manually with the same working directory to see its real error output.
- Fix or remove the offending `hooks.pre` entry in .goreleaser.yaml.
- Ensure any binaries/scripts the hook calls are installed and on PATH in the CI environment.
- Check the hook's templates ({{ .Images }}, {{ .Dockerfile }}, {{ .ContextDir }}) resolve correctly.
Example fix
// before (.goreleaser.yaml)
dockers_v2:
- hooks:
pre:
- ./scripts/validate.sh
// after (ensure executable or use sh)
dockers_v2:
- hooks:
pre:
- sh ./scripts/validate.sh Defensive patterns
Strategy: validation
Validate before calling
// shell: pre-flight check that hook commands exist before running goreleaser
for cmd in $(yq '.dockers_v2[].hooks.pre[]' .goreleaser.yaml); do
command -v "$(echo "$cmd" | awk '{print $1}')" >/dev/null || { echo "missing hook binary: $cmd"; exit 1; }
done Try / catch
err := goreleaserRelease(ctx)
if err != nil && strings.Contains(err.Error(), "pre hook failed") {
// surface the underlying hook output already logged by runHook
return fmt.Errorf("docker pre hook failed; check hook command and PATH: %w", err)
} Prevention
- Keep pre hooks simple and dependency-free; install dependencies in an earlier CI step
- Use `sh -c` style entries so scripts don't need the execute bit
- Smoke-test hooks locally with the same working directory goreleaser uses
- Verify every binary a hook calls is on PATH in the CI image
When it happens
Trigger: A `dockers_v2.hooks.pre` entry in .goreleaser.yaml returns a non-zero exit code, references a binary not on PATH, or its own template fails, during the docker build image step.
Common situations: Hook script missing execute permission, depending on tools only present locally but not in CI, using template fields (images/dockerfile/context dir) incorrectly, or a linter/formatter hook failing on generated files.
Related errors
- post hook failed: %w
- no tags provided
- %w: %s
- failed to create %s: %w
- invalid use: %s, valid options are %v
AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05).
Data as JSON: /api/errors/9a22656a43e5f365.
Report an issue: GitHub.