{"record":{"id":"594c04b56d5836f3","repo":"hashicorp/packer","slug":"unable-to-write-s-s","errorCode":null,"errorMessage":"Unable to write %s: %s","messagePattern":"Unable to write (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/manifest/post-processor.go","lineNumber":170,"sourceCode":"\t\tif err = json.Unmarshal(contents, manifestFile); err != nil {\n\t\t\treturn source, true, true, fmt.Errorf(\"Unable to parse content from %s: %s\", p.config.OutputPath, err)\n\t\t}\n\t}\n\n\t// If -force is set and we are not on same run, truncate the file. Otherwise\n\t// we will continue to add new builds to the existing manifest file.\n\tif p.config.PackerForce && os.Getenv(\"PACKER_RUN_UUID\") != manifestFile.LastRunUUID {\n\t\tmanifestFile = &ManifestFile{}\n\t}\n\n\t// Add the current artifact to the manifest file\n\tmanifestFile.Builds = append(manifestFile.Builds, *artifact)\n\tmanifestFile.LastRunUUID = os.Getenv(\"PACKER_RUN_UUID\")\n\n\t// Write JSON to disk\n\tif out, err := json.MarshalIndent(manifestFile, \"\", \"  \"); err == nil {\n\t\tif err = os.WriteFile(p.config.OutputPath, out, 0664); err != nil {\n\t\t\treturn source, true, true, fmt.Errorf(\"Unable to write %s: %s\", p.config.OutputPath, err)\n\t\t}\n\t} else {\n\t\treturn source, true, true, fmt.Errorf(\"Unable to marshal JSON %s\", err)\n\t}\n\n\t// The manifest should never delete the artifacts it is set to record, so it\n\t// forcibly sets \"keep\" to true.\n\treturn source, true, true, nil\n}\n\nfunc createInterpolatedCustomData(config *Config, customData string) (string, error) {\n\tinterpolatedCmd, err := interpolate.Render(customData, &config.ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Error interpolating custom data: %s\", err)\n\t}\n\treturn interpolatedCmd, nil\n}\n","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/manifest/post-processor.go#L152-L188","documentation":"After appending the new build, the post-processor serializes the manifest with json.MarshalIndent and writes it to output_path via os.WriteFile. If the write fails, PostProcess returns this error while still keeping the source artifact. The build itself succeeded, but the manifest could not be persisted.","triggerScenarios":"os.WriteFile(p.config.OutputPath, out, 0664) fails — output directory missing, permission denied, output_path is a directory, read-only filesystem, or disk full.","commonSituations":"output_path's parent directory does not exist (packer does not create nested dirs for the manifest); manifest locked/owned by another user from a prior sudo run; writing to a read-only CI volume or a path whose directory was cleaned mid-run.","solutions":["Create the parent directory of output_path (mkdir -p) before running packer.","Fix permissions on the existing manifest/its directory (chown/chmod) or run packer as the same user that owns it.","Verify output_path is a file path on a writable, non-full filesystem.","Simplify output_path to a plain writable path like `packer-manifest.json` to rule out interpolation issues."],"exampleFix":"// before\noutput_path = \"artifacts/manifests/packer-manifest.json\" // dir doesn't exist\n// after\nmkdir -p artifacts/manifests\n# or\noutput_path = \"packer-manifest.json\"","handlingStrategy":"validation","validationCode":"# preflight: manifest's parent dir exists, is writable, and is a file path\nMP=\"artifacts/manifests/packer-manifest.json\"\nmkdir -p \"$(dirname \"$MP\")\"\n[ ! -d \"$MP\" ] && [ -w \"$(dirname \"$MP\")\" ] || exit 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["mkdir -p the parent of output_path before building.","Verify output_path is not a directory.","Ensure the filesystem is writable and has free space.","Keep manifest ownership consistent with the packer user."],"tags":["file-io","manifest","post-processor","permissions"],"backgroundTag":"file-write-failed","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"}