{"record":{"id":"d6cdbe08cb811483","repo":"hashicorp/packer","slug":"unable-to-open-file-s-s","errorCode":null,"errorMessage":"unable to open file %s: %s","messagePattern":"unable to open file (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/checksum/post-processor.go","lineNumber":145,"sourceCode":"\t\t\tchecksumFile, err := interpolate.Render(p.config.OutputPath, &p.config.ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, false, true, err\n\t\t\t}\n\n\t\t\tif _, err := os.Stat(checksumFile); err != nil {\n\t\t\t\tnewartifact.files = append(newartifact.files, checksumFile)\n\t\t\t}\n\t\t\tif err := os.MkdirAll(filepath.Dir(checksumFile), os.FileMode(0755)); err != nil {\n\t\t\t\treturn nil, false, true, fmt.Errorf(\"unable to create dir: %s\", err.Error())\n\t\t\t}\n\t\t\tfw, err := os.OpenFile(checksumFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, false, true, fmt.Errorf(\"unable to create file %s: %s\", checksumFile, err.Error())\n\t\t\t}\n\t\t\tfr, err := os.Open(art)\n\t\t\tif err != nil {\n\t\t\t\tfw.Close()\n\t\t\t\treturn nil, false, true, fmt.Errorf(\"unable to open file %s: %s\", art, err.Error())\n\t\t\t}\n\n\t\t\tif _, err = io.Copy(h, fr); err != nil {\n\t\t\t\tfr.Close()\n\t\t\t\tfw.Close()\n\t\t\t\treturn nil, false, true, fmt.Errorf(\"unable to compute %s hash for %s\", ct, art)\n\t\t\t}\n\t\t\tfr.Close()\n\t\t\t_, _ = fw.WriteString(fmt.Sprintf(\"%x\\t%s\\n\", h.Sum(nil), filepath.Base(art)))\n\t\t\tfw.Close()\n\t\t\th.Reset()\n\t\t}\n\t}\n\n\t// sets keep and forceOverride to true because we don't want to accidentally\n\t// delete the very artifact we're checksumming.\n\treturn newartifact, true, true, nil\n}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/checksum/post-processor.go#L127-L163","documentation":"PostProcess-time failure in the checksum post-processor: it opens each artifact file from the input artifact with os.Open to hash it; when the artifact file cannot be opened, the writer is closed and the whole post-process aborts with keep=true. The artifact path and wrapped OS error are reported.","triggerScenarios":"os.Open(art) fails for a file listed in the artifact's Files() — the builder's output was deleted/moved between build and post-process, the artifact reports a stale path (common with chained post-processors like compress/artifice changing output locations), or permissions changed.","commonSituations":"Chaining checksum after another post-processor that consumed/renamed the files; running on shared output where the file was cleaned up; the builder emitting file paths that were relative to a different working directory.","solutions":["Verify the artifact files still exist at the reported paths at the time PostProcess runs","Reorder post-processors so checksum runs directly on the builder output if a prior post-processor moves/deletes files","Check file permissions on the artifact output directory and files","Keep output files in the same directory tree Packer wrote them to and avoid external cleanup during the build"],"exampleFix":"// before\nfr, err := os.Open(art)\nif err != nil {\n  fw.Close()\n  return nil, false, true, fmt.Errorf(\"unable to open file %s: %s\", art, err.Error())\n}\n// after\nfr, err := os.Open(art)\nif err != nil {\n  fw.Close()\n  return nil, false, true, fmt.Errorf(\"unable to open file %s: %w\", art, err)\n}","handlingStrategy":"validation","validationCode":"// Go: verify every artifact file exists before post-processing\nfor _, f := range artifact.Files() {\n    if _, err := os.Stat(f); err != nil {\n        log.Fatalf(\"artifact file missing before checksum: %s: %v\", f, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"artifact, _, _, err := pp.PostProcess(ctx, ui, art)\nif err != nil {\n    if strings.Contains(err.Error(), \"unable to open file\") {\n        // artifact files vanished: fix post-processor order / stale paths\n    }\n    return err\n}","preventionTips":["Run checksum before post-processors that move/compress/delete artifact files","Verify artifact.Files() paths exist right before PostProcess in custom tooling","Don't clean up the build output directory while Packer is running","Use absolute, stable output locations when chaining post-processors"],"tags":["packer","post-processor","checksum","filesystem","artifact"],"backgroundTag":"file-open-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"}