{"record":{"id":"e70b45dd70603ac4","repo":"hashicorp/packer","slug":"unable-to-open-s-for-reading-s","errorCode":null,"errorMessage":"Unable to open %s for reading: %s","messagePattern":"Unable to open (.+?) for reading: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/manifest/post-processor.go","lineNumber":146,"sourceCode":"\n\t// Create a lock file with exclusive access. If this fails we will retry\n\t// after a delay.\n\tlockFilename := p.config.OutputPath + \".lock\"\n\tfor i := 0; i < 3; i++ {\n\t\t// The file should not be locked for very long so we'll keep this short.\n\t\ttime.Sleep((time.Duration(i) * 200 * time.Millisecond))\n\t\t_, err = os.OpenFile(lockFilename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)\n\t\tif err == nil {\n\t\t\tbreak\n\t\t}\n\t\tlog.Printf(\"Error locking manifest file for reading and writing. Will sleep and retry. %s\", err)\n\t}\n\tdefer os.Remove(lockFilename)\n\n\t// Read the current manifest file from disk\n\tvar contents []byte\n\tif contents, err = os.ReadFile(p.config.OutputPath); err != nil && !os.IsNotExist(err) {\n\t\treturn source, true, true, fmt.Errorf(\"Unable to open %s for reading: %s\", p.config.OutputPath, err)\n\t}\n\n\t// Parse the manifest file JSON, if we have one\n\tmanifestFile := &ManifestFile{}\n\tif len(contents) > 0 {\n\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)","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/manifest/post-processor.go#L128-L164","documentation":"During PostProcess the manifest post-processor reads the existing packer-manifest.json from output_path to append the new build. If os.ReadFile fails with an error other than NotExist, it returns this error (keeping the source artifact and force flag). A non-notexist failure means the manifest exists but can't be read.","triggerScenarios":"os.ReadFile(p.config.OutputPath) fails and the error is not os.IsNotExist — e.g. permission denied on the manifest file, output_path resolves to a directory, or an I/O error on the volume.","commonSituations":"packer-manifest.json left owned by root from a previous sudo run; output_path set to a directory instead of a file; read-only or unmounted output filesystem; NFS permission issues.","solutions":["Check permissions on the existing manifest file: chown/chmod it so the packer user can read it (or delete it if stale).","Verify output_path points to a file, not a directory.","Confirm the output directory is on a mounted, writable filesystem.","If the manifest is stale/corrupt, remove it and re-run — the post-processor recreates it."],"exampleFix":"// before: manifest owned by root, packer runs as user\nsudo chown $(whoami) packer-manifest.json\n// or remove stale manifest\nrm packer-manifest.json","handlingStrategy":"validation","validationCode":"# preflight manifest readability\nMP=packer-manifest.json\nif [ -e \"$MP\" ]; then [ -f \"$MP\" ] && [ -r \"$MP\" ] || { echo \"manifest unreadable: $MP\"; exit 1; }; fi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run packer consistently as one user; avoid sudo mixing on manifest files.","Ensure output_path is a file, not a directory.","Delete stale manifests from previous (root) runs.","Check mounts are up before CI runs."],"tags":["file-io","manifest","post-processor","permissions"],"backgroundTag":"file-read-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"}