goreleaser/goreleaser · error
could not write image digest: %w
Error message
could not write image digest: %w
What it means
GoReleaser's dockerdigest pipe renders the configured `dockerdigest.name_template` to get a file name, joins it with the dist directory, and writes the computed image digest to that file with os.WriteFile. This error wraps any failure from that write call. It means GoReleaser could not persist the digest artifact to disk, even though the digest itself was successfully computed.
Source
Thrown at internal/pipe/dockerdigest/digest.go:70
return strings.Compare(a.Name, b.Name)
})
var data bytes.Buffer
for _, img := range images {
digest := artifact.ExtraOr(*img, artifact.ExtraDigest, "")
if idx := strings.IndexRune(digest, ':'); idx != -1 {
digest = digest[idx+1:]
}
_, _ = fmt.Fprintf(&data, "%s %s\n", digest, img.Name)
}
filename, err := tmpl.New(ctx).Apply(ctx.Config.DockerDigest.NameTemplate)
if err != nil {
return err
}
filename = filepath.Join(ctx.Config.Dist, filename)
if err := os.WriteFile(filename, data.Bytes(), 0o644); err != nil {
return fmt.Errorf("could not write image digest: %w", err)
}
log.WithField("path", filename).Info("written digest file")
return nil
}
View on GitHub (pinned to f5edd73956)
Solutions
- Check the rendered file name from docker_digests.name_template — remove characters illegal on your filesystem (':' or '/' are common culprits).
- Verify dist/ exists, is writable by the current user, and contains no directory with the same name as the digest file.
- Free disk space or fix filesystem permissions (chmod/chown dist/), then rerun the release.
- If the write target is intentionally read-only, disable the digest artifact instead of redirecting it.
Example fix
// before
docker_digests:
name_template: "digest_{{ .Tag }}:latest.txt"
// after
docker_digests:
name_template: "digest_{{ .Tag }}.txt" Defensive patterns
Strategy: validation
Validate before calling
// before releasing: ensure the digest target path is writable
const os = require('child_process');
const name = 'digest_v1.0.0.txt'; // render your name_template the same way
fs.accessSync(path.join(distDir, path.dirname(name) || '.'), fs.constants.W_OK);
if (fs.existsSync(path.join(distDir, name)) && fs.statSync(path.join(distDir, name)).isDirectory()) {
throw new Error(`digest path ${name} is a directory`);
} Prevention
- Keep name_template free of OS-illegal characters (no ':' or '/').
- Never run releases as root against a user-owned dist/.
- Check free disk space before CI release jobs.
- Use --clean or wipe dist/ at the start of each release.
When it happens
Trigger: os.WriteFile fails while publishing, e.g. the rendered template produced an invalid filename, the dist/<name> path is a directory or otherwise unwritable, the disk is full, or the process lacks write permission on dist/.
Common situations: A name_template containing characters invalid on the OS filesystem (e.g. ':' on Windows); dist/ owned by another user after running with sudo; CI working directory permissions; read-only or full disk during a release.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- no tags provided
- node: write sea-config.json: %w
- archive named %s already exists. Check your archive name tem
- failed to create directory %s: %w
- failed to close archive file %s: %w
AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05).
Data as JSON: /api/errors/9bd6ad63ef0d8799.
Report an issue: GitHub.