{"record":{"id":"144f056abd981447","repo":"hyperledger/fabric","slug":"error-creating-temp-file-in-directory-s","errorCode":null,"errorMessage":"error creating temp file in directory '%s'","messagePattern":"error creating temp file in directory '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/persistence/persistence.go","lineNumber":50,"sourceCode":"\tRemove(name string) error\n\tWriteFile(string, string, []byte) error\n\tMakeDir(string, os.FileMode) error\n\tExists(path string) (bool, error)\n}\n\n// FilesystemIO is the production implementation of the IOWriter interface\ntype FilesystemIO struct{}\n\n// WriteFile writes a file to the filesystem; it does so atomically\n// by first writing to a temp file and then renaming the file so that\n// if the operation crashes midway we're not stuck with a bad package\nfunc (f *FilesystemIO) WriteFile(path, name string, data []byte) error {\n\tif path == \"\" {\n\t\treturn errors.New(\"empty path not allowed\")\n\t}\n\ttmpFile, err := os.CreateTemp(path, \".ccpackage.\")\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error creating temp file in directory '%s'\", path)\n\t}\n\tdefer os.Remove(tmpFile.Name())\n\n\tif n, err := tmpFile.Write(data); err != nil || n != len(data) {\n\t\tif err == nil {\n\t\t\terr = errors.Errorf(\n\t\t\t\t\"failed to write the entire content of the file, expected %d, wrote %d\",\n\t\t\t\tlen(data), n,\n\t\t\t)\n\t\t}\n\t\treturn errors.Wrapf(err, \"error writing to temp file '%s'\", tmpFile.Name())\n\t}\n\n\tif err := tmpFile.Close(); err != nil {\n\t\treturn errors.Wrapf(err, \"error closing temp file '%s'\", tmpFile.Name())\n\t}\n\n\tif err := os.Rename(tmpFile.Name(), filepath.Join(path, name)); err != nil {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/persistence/persistence.go#L32-L68","documentation":"WriteFile creates a uniquely-named temporary file (prefix .ccpackage.) inside the target directory via os.CreateTemp before atomically renaming it. If the OS refuses to create that temp file, the underlying error is wrapped with this message.","triggerScenarios":"os.CreateTemp(path, \".ccpackage.\") fails because the directory does not exist, is not writable by the peer process, or a filesystem/permission/quota error occurs.","commonSituations":"Peer running as non-root while the chaincode install directory is owned by root; disk full; the _lifecycle chaincodes directory was never created (Initialization skipped) or was deleted; read-only mounted volume (e.g. container filesystem).","solutions":["Ensure the target directory exists and is owned/writable by the peer user (e.g. `chown -R peer:peer /var/hyperledger/production/lifecycle/chaincodes`)","Check disk space (`df -h`) and mount status of the volume","Call NewStore/Initialize first so MakeDir creates the directory with 0750 before writing","Review the wrapped underlying OS error for the exact cause (ENOENT vs EACCES vs ENOSPC)"],"exampleFix":"// before\nstore := &persistence.Store{Path: p, ReadWriter: &persistence.FilesystemIO{}} // dir may not exist\n\n// after\nstore, err := persistence.NewStore(p, &persistence.FilesystemIO{}) // Initialize() creates the dir","handlingStrategy":"validation","validationCode":"func ensureWritableDir(p string) error {\n    info, err := os.Stat(p)\n    if os.IsNotExist(err) { return errors.New(\"install directory does not exist\") }\n    if !info.IsDir() { return errors.New(\"install path is not a directory\") }\n    if err := unix.Access(p, unix.W_OK); err != nil { return errors.New(\"install directory not writable\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := io.WriteFile(path, name, data); err != nil {\n    var werr *os.PathError\n    if errors.As(err, &werr) && errors.Is(werr.Err, syscall.EACCES) {\n        return fmt.Errorf(\"fix permissions on %s: %w\", path, err)\n    }\n    return err\n}","preventionTips":["Provision the chaincode install directory with correct ownership before peer start","Monitor disk space and quotas on the peer's data volume","Always initialize the store (NewStore) so the directory is created with 0750"],"tags":["filesystem","permissions","io"],"backgroundTag":"permission-denied","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}