hashicorp/packer · error
write attestation %q: %w
Error message
write attestation %q: %w
What it means
After marshaling the unsigned attestation, writeAttestation writes it to `outputPath` via atomicWriteFile. Any filesystem error (permissions, missing directory, disk full, path is a directory) is wrapped as `write attestation %q: %w` with the path quoted.
Source
Thrown at post-processor/provenance/post-processor.go:289
statement := internalprovenance.WrapInToto(subjects, predicateType, predicate)
if err := p.writeAttestation(ctx, ui, statement, paths.SBOMAttestation); err != nil {
return err
}
ui.Say(fmt.Sprintf("Wrote SBOM to %s", paths.SBOMRaw))
return nil
}
func (p *PostProcessor) writeAttestation(ctx context.Context, ui packersdk.Ui, statement interface{}, outputPath string) error {
if p.config.SigningMode == internalattestation.SigningModeNone {
payload, err := json.MarshalIndent(statement, "", " ")
if err != nil {
return fmt.Errorf("marshal attestation payload: %w", err)
}
if err := atomicWriteFile(outputPath, payload, 0664); err != nil {
return fmt.Errorf("write attestation %q: %w", outputPath, err)
}
ui.Say(fmt.Sprintf("Wrote attestation to %s", outputPath))
return nil
}
backendConfig, err := p.signingBackendConfig()
if err != nil {
return err
}
signer, verifier, err := p.signingResources(ctx, backendConfig)
if err != nil {
return err
}
payload, err := internalattestation.MarshalPayload(statement)
if err != nil {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Create the parent directory: `mkdir -p $(dirname <output_path>)`.
- Check write permissions on the target directory (`ls -ld`, run as the right user).
- Ensure outputPath is a file path, not an existing directory.
- Check disk space and mount status if the error mentions 'no space left' or 'read-only'.
Example fix
// before
post-processor "provenance" { output_path = "/att/manifest.json" } // /att missing
// after
post-processor "provenance" { output_path = "./attestations/manifest.json" } // dir pre-created Defensive patterns
Strategy: validation
Validate before calling
// check the output path is writable before the build
path := cfg.OutputPath
if dir := filepath.Dir(path); dir != "." {
if err := os.MkdirAll(dir, 0o755); err != nil { return err }
}
if info, err := os.Stat(path); err == nil && info.IsDir() {
return fmt.Errorf("output_path %q is a directory", path)
}
if f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o664); err != nil {
return err
} else { f.Close() } Try / catch
if err := pp.PostProcess(ctx, ui, artifact); err != nil {
if strings.Contains(err.Error(), "write attestation") {
// check permissions/existence of the quoted path, then retry once after mkdir
}
} Prevention
- Pre-create output directories in CI before running packer.
- Run packer as a user with write access to output_dir.
- Avoid paths on read-only or tmpfs mounts for artifacts.
- Verify disk space before long builds.
When it happens
Trigger: PostProcess/writeSBOMAttestation with an output_path whose parent directory doesn't exist, is read-only, or is owned by another user; or outputPath itself is an existing directory.
Common situations: Running packer in a container where the output dir was never created; SELinux/read-only mounts; specifying a path inside a non-existent `output_dir`.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- create output dir %q: %w
- read attestation %q: %w
- attestation subject does not match artifact %q
- could not create plugin folder %q: %w
- could not create final plugin binary file: %w
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/144fb2e726cdfa0a.
Report an issue: GitHub.