{"record":{"id":"c67c1baad209cbc4","repo":"hashicorp/packer","slug":"create-output-dir-q-w","errorCode":null,"errorMessage":"create output dir %q: %w","messagePattern":"create output dir %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/provenance/post-processor.go","lineNumber":640,"sourceCode":"func redactSensitiveVariables(userVariables map[string]string, sensitiveKeys []string) {\n\tfor _, key := range sensitiveKeys {\n\t\tif _, ok := userVariables[key]; ok {\n\t\t\tuserVariables[key] = redactedSensitiveValue\n\t\t}\n\t}\n}\n\nfunc (p *PostProcessor) outputPaths(source packersdk.Artifact) (outputPaths, error) {\n\tbaseDir := p.config.OutputDir\n\tif baseDir == \"\" && len(source.Files()) > 0 {\n\t\tbaseDir = filepath.Dir(source.Files()[0])\n\t}\n\tif baseDir == \"\" {\n\t\tbaseDir = \".\"\n\t}\n\n\tif err := os.MkdirAll(baseDir, 0755); err != nil {\n\t\treturn outputPaths{}, fmt.Errorf(\"create output dir %q: %w\", baseDir, err)\n\t}\n\n\tname := p.outputStem(source)\n\tsbomFormat := internalsbom.FormatCycloneDX\n\tif parsed, err := internalsbom.ParseFormatFromArgs(p.config.SBOMFormat); err == nil {\n\t\tsbomFormat = parsed\n\t}\n\tsbomRaw := filepath.Join(baseDir, name+\".sbom.cdx.json\")\n\tif sbomFormat == internalsbom.FormatSPDX {\n\t\tsbomRaw = filepath.Join(baseDir, name+\".sbom.spdx.json\")\n\t}\n\n\treturn outputPaths{\n\t\tBaseDir:             baseDir,\n\t\tStem:                name,\n\t\tProvenanceStatement: filepath.Join(baseDir, name+\".provenance.json\"),\n\t\tSBOMRaw:             sbomRaw,\n\t\tSBOMAttestation:     filepath.Join(baseDir, name+\".sbom.att.json\"),","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/provenance/post-processor.go#L622-L658","documentation":"outputPaths could not create (or create the parents of) the base directory where provenance/SBOM outputs will be written, using os.MkdirAll with mode 0755. The wrapped OS error carries the real reason.","triggerScenarios":"PostProcess calls outputPaths; baseDir (derived from output path config or the working directory) cannot be created — permission denied, read-only filesystem, path segment is an existing file, or invalid path characters.","commonSituations":"Running packer in a read-only container FS; output directory path collides with an existing file; output path points outside a mounted volume; running as non-root writing to a privileged path.","solutions":["Fix permissions on the parent directory or run packer as a user with write access","Correct the output path in the post-processor config so it is not blocked by an existing file","Ensure the output path is inside a writable volume in containers/CI","Free disk space if the failure was caused by a full disk"],"exampleFix":"// before\npost-processor provenance {\n  output = \"/root/attestations\"\n}\n// after\npost-processor provenance {\n  output = \"./attestations\"\n}","handlingStrategy":"try-catch","validationCode":"// Pre-flight in shell before packer build:\n// mkdir -p \"$OUTPUT_DIR\" && test -w \"$OUTPUT_DIR\"\nif err := os.MkdirAll(baseDir, 0755); err != nil {\n    return fmt.Errorf(\"output dir not creatable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := pp.PostProcess(ctx, artifact); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        // fix permissions / existing-file collision on pe.Path\n    }\n}","preventionTips":["Point provenance output at a directory inside a writable volume","In CI containers, chown the output directory before running packer","Never set output to a path where a parent component is an existing file"],"tags":["packer","provenance","filesystem","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}