hyperledger/fabric · critical

Could not build blockfilesInfo info from block files: %s

Error message

Could not build blockfilesInfo info from block files: %s

What it means

Panic when constructBlockfilesInfo cannot rebuild blockfilesInfo by scanning the block files directory (used only when the DB checkpoint record is absent, e.g. first start after index reset). It means the FS scan failed (stat/read errors on files) so block storage cannot initialize.

Source

Thrown at common/ledger/blkstorage/blockfile_mgr.go:111

	  *)  Updates blockchain info used by the APIs
*/
func newBlockfileMgr(id string, conf *Conf, indexConfig *IndexConfig, indexStore *leveldbhelper.DBHandle) (*blockfileMgr, error) {
	logger.Debugf("newBlockfileMgr() initializing file-based block storage for ledger: %s ", id)
	rootDir := conf.getLedgerBlockDir(id)
	_, err := fileutil.CreateDirIfMissing(rootDir)
	if err != nil {
		panic(fmt.Sprintf("Error creating block storage root dir [%s]: %s", rootDir, err))
	}
	mgr := &blockfileMgr{rootDir: rootDir, conf: conf, db: indexStore, cache: newCache(defaultBlockCacheSizeBytes)}

	blockfilesInfo, err := mgr.loadBlkfilesInfo()
	if err != nil {
		panic(fmt.Sprintf("Could not get block file info for current block file from db: %s", err))
	}
	if blockfilesInfo == nil {
		logger.Info(`Getting block information from block storage`)
		if blockfilesInfo, err = constructBlockfilesInfo(rootDir); err != nil {
			panic(fmt.Sprintf("Could not build blockfilesInfo info from block files: %s", err))
		}
		logger.Debugf("Info constructed by scanning the blocks dir = %s", spew.Sdump(blockfilesInfo))
	} else {
		logger.Debug(`Syncing block information from block storage (if needed)`)
		syncBlockfilesInfoFromFS(rootDir, blockfilesInfo)
	}
	err = mgr.saveBlkfilesInfo(blockfilesInfo, true)
	if err != nil {
		panic(fmt.Sprintf("Could not save next block file info to db: %s", err))
	}

	currentFileWriter, err := newBlockfileWriter(deriveBlockfilePath(rootDir, blockfilesInfo.latestFileNumber))
	if err != nil {
		panic(fmt.Sprintf("Could not open writer to current file: %s", err))
	}
	err = currentFileWriter.truncateFile(blockfilesInfo.latestFileSize)
	if err != nil {
		panic(fmt.Sprintf("Could not truncate current file to known size in db: %s", err))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Restore the complete chains/<ledgerID> block files (index and chains dirs must come from the same backup)
  2. Fix permissions/ownership of the block files so the scanner can stat them
  3. If the ledger is disposable, delete both the ledger dir and its index entries to start fresh

Example fix

// before: restoring only the index DB without chains files
// after: restore index and chains dirs together from the same snapshot
// rsync -a snapshot/ledgersData/ ledgersData/
Defensive patterns

Strategy: validation

Validate before calling

// ensure FS scan will succeed: all existing block files are statable
entries, err := os.ReadDir(filepath.Join(rootDir))
if err != nil { return err }
for _, e := range entries {
    if _, err := os.Lstat(filepath.Join(rootDir, e.Name())); err != nil {
        return fmt.Errorf("unreadable entry %s: %w", e.Name(), err)
    }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        err = fmt.Errorf("cannot reconstruct blockfilesInfo: %v", r)
    }
}()

Prevention

When it happens

Trigger: constructBlockfilesInfo returns an error — typically getFileInfoOrPanic Lstat failure on a block file, or inability to read the last file — when blockfilesInfo == nil during newBlockfileMgr.

Common situations: Block files missing or unreadable while the index DB was reset/empty (mismatched index vs chains dirs); partial backup restore; permission problems on chains/<ledgerID>.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/7b05d0a48e7ec7fd. Report an issue: GitHub.