{"record":{"id":"b34b8d6c40c49291","repo":"hyperledger/fabric","slug":"error-reading-dir-s","errorCode":null,"errorMessage":"error reading dir %s","messagePattern":"error reading dir (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/ledger/blkstorage/blockfile_helper.go","lineNumber":139,"sourceCode":"\t}\n\tdefer s.close()\n\tbb, err := s.nextBlockBytes()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tblockInfo, err := extractSerializedBlockInfo(bb)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn blockInfo.blockHeader.Number, nil\n}\n\nfunc retrieveLastFileSuffix(rootDir string) (int, error) {\n\tlogger.Debugf(\"retrieveLastFileSuffix()\")\n\tbiggestFileNum := -1\n\tfilesInfo, err := os.ReadDir(rootDir)\n\tif err != nil {\n\t\treturn -1, errors.Wrapf(err, \"error reading dir %s\", rootDir)\n\t}\n\tfor _, fileInfo := range filesInfo {\n\t\tname := fileInfo.Name()\n\t\tif fileInfo.IsDir() || !isBlockFileName(name) {\n\t\t\tlogger.Debugf(\"Skipping File name = %s\", name)\n\t\t\tcontinue\n\t\t}\n\t\tfileSuffix := strings.TrimPrefix(name, blockfilePrefix)\n\t\tfileNum, err := strconv.Atoi(fileSuffix)\n\t\tif err != nil {\n\t\t\treturn -1, err\n\t\t}\n\t\tif fileNum > biggestFileNum {\n\t\t\tbiggestFileNum = fileNum\n\t\t}\n\t}\n\tlogger.Debugf(\"retrieveLastFileSuffix() - biggestFileNum = %d\", biggestFileNum)\n\treturn biggestFileNum, err","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockfile_helper.go#L121-L157","documentation":"Wraps the os.ReadDir error when retrieveLastFileSuffix cannot list the block storage root directory. This function scans for the highest-numbered blockfile_<n> to build blockfilesInfo; without a directory listing the ledger cannot determine its file layout. Returned by constructBlockfilesInfo, resetToGenesisBlk, and rollback paths.","triggerScenarios":"retrieveLastFileSuffix(rootDir) calls os.ReadDir(rootDir); failure means the rootDir does not exist, is not readable (permissions), or an I/O error occurs.","commonSituations":"peer.fileSystemPath misconfigured (wrong mount, volume not attached); ledger directory deleted while the peer runs; permission problems after running the peer as different users (root-created files unreadable by the peer user); read-only mounted volume.","solutions":["Verify the ledger root directory exists and is readable by the peer process (check ledgersData/chains/<chainID>)","Fix permissions/ownership on the ledger directory (match the peer's runtime user)","Correct peer.fileSystemPath or mount the expected volume","If the directory was deleted, restore from backup or re-create the chain (re-join/re-sync)"],"exampleFix":"// before\nfilesInfo, err := os.ReadDir(rootDir)\nif err != nil { return -1, err }\n// after: validate up front\nif info, err := os.Stat(rootDir); err != nil || !info.IsDir() {\n    return -1, fmt.Errorf(\"ledger dir %s missing or not a directory\", rootDir)\n}\nfilesInfo, err := os.ReadDir(rootDir)\nif err != nil { return -1, errors.Wrapf(err, \"error reading dir %s\", rootDir) }","handlingStrategy":"validation","validationCode":"info, err := os.Stat(rootDir)\nif err != nil {\n    return fmt.Errorf(\"ledger root %s missing: %w\", rootDir, err)\n}\nif !info.IsDir() {\n    return fmt.Errorf(\"%s is not a directory\", rootDir)\n}\nif f, err := os.Open(rootDir); err != nil {\n    return fmt.Errorf(\"ledger root %s not readable: %w\", rootDir, err)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"suffix, err := retrieveLastFileSuffix(rootDir)\nif err != nil {\n    if os.IsNotExist(errors.Cause(err)) {\n        return initializeEmptyLedgerDir(rootDir)\n    }\n    return err\n}","preventionTips":["Verify peer.fileSystemPath and volume mounts at startup","Run the peer as one consistent user; chown ledger dirs after image upgrades","Never mount the ledger volume read-only","Alert on deletion of the ledgersData directory tree"],"tags":["fabric","ledger","filesystem","directory"],"backgroundTag":"file-not-found","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"}