{"record":{"id":"d6f16b909268ae62","repo":"hyperledger/fabric","slug":"failed-to-read-ledger-directory-s","errorCode":null,"errorMessage":"failed to read ledger directory %s","messagePattern":"failed to read ledger directory (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"common/ledger/blkstorage/blockstore_provider.go","lineNumber":74,"sourceCode":"\tstats           *stats\n}\n\n// NewProvider constructs a filesystem based block store provider\nfunc NewProvider(conf *Conf, indexConfig *IndexConfig, metricsProvider metrics.Provider) (*BlockStoreProvider, error) {\n\tdbConf := &leveldbhelper.Conf{\n\t\tDBPath:         conf.getIndexDir(),\n\t\tExpectedFormat: dataFormatVersion(indexConfig),\n\t}\n\n\tp, err := leveldbhelper.NewProvider(dbConf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdirPath := conf.getChainsDir()\n\tif _, err := os.Stat(dirPath); err != nil {\n\t\tif !os.IsNotExist(err) { // NotExist is the only permitted error type\n\t\t\treturn nil, errors.Wrapf(err, \"failed to read ledger directory %s\", dirPath)\n\t\t}\n\n\t\tlogger.Info(\"Creating new file ledger directory at\", dirPath)\n\t\tif err = os.MkdirAll(dirPath, 0o755); err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"failed to create ledger directory: %s\", dirPath)\n\t\t}\n\t}\n\n\tstats := newStats(metricsProvider)\n\treturn &BlockStoreProvider{conf, indexConfig, p, stats}, nil\n}\n\n// Open opens a block store for given ledgerid.\n// If a blockstore is not existing, this method creates one\n// This method should be invoked only once for a particular ledgerid\nfunc (p *BlockStoreProvider) Open(ledgerid string) (*BlockStore, error) {\n\tindexStoreHandle := p.leveldbProvider.GetDBHandle(ledgerid)\n\treturn newBlockStore(ledgerid, p.conf, p.indexConfig, indexStoreHandle, p.stats)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/blkstorage/blockstore_provider.go#L56-L92","documentation":"NewProvider for the file-based blockstore stats the chains directory (conf.getChainsDir(), typically under FileLedger/ledgerData). If os.Stat fails with anything other than NotExist — e.g. permission denied or an I/O error — the error is wrapped with this message and provider creation aborts. Note that NotExist is tolerated and the directory is created.","triggerScenarios":"Starting the peer (or calling NewProvider/openBlockStorage) when the ledger directory exists but is unreadable: wrong ownership/permissions, an EACCES/EPERM/EIO from the filesystem, or the path being an unreadable mount.","commonSituations":"Peer running as non-root against a ledgerData dir owned by another user, read-only or full mount, container volume permission mismatch after image upgrade, Kubernetes securityContext UID changes.","solutions":["Run the wrapped cause (os.Stat error) to see the OS-level reason (permission denied vs I/O).","Fix permissions on the ledger directory: chown/chmod so the peer process user has rwx.","Check that the volume/mount is writable and not full (df, mount ro/rw).","Verify the peer's fileLedger location config matches the directory actually provisioned.","If migrating containers/k8s, align the securityContext runAsUser/FSGroup with the directory owner."],"exampleFix":"// before: peer fails to start with unreadable ledger dir\n// after: provision correct ownership before starting\n// $ sudo chown -R 7051:7051 /var/hyperledger/production/ledgersData\n// $ chmod -R u+rwX /var/hyperledger/production/ledgersData","handlingStrategy":"validation","validationCode":"dirPath := filepath.Join(ledgerDataPath, \"chains\")\nif fi, err := os.Stat(dirPath); err != nil && !os.IsNotExist(err) {\n    return fmt.Errorf(\"cannot access ledger dir %s: %v — fix permissions/mount before starting peer\", dirPath, err)\n}","typeGuard":null,"tryCatchPattern":"provider, err := blkstorage.NewProvider(conf)\nif err != nil && strings.Contains(err.Error(), \"failed to read ledger directory\") {\n    return fmt.Errorf(\"check ownership/permissions/mount of the ledger directory: %w\", err)\n}\nif err != nil { return err }","preventionTips":["Provision the ledger directory with correct ownership (peer UID, e.g. chown 7051) before startup.","Verify volumes are mounted read-write and have free space in container/K8s deployments.","Keep securityContext runAsUser/FSGroup aligned with the ledger directory owner.","Test the ledger path with a simple stat/write check in your startup health script."],"tags":["filesystem","permissions","ledger","startup"],"backgroundTag":"ledger-directory-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"}