hyperledger/fabric · critical

error retrieving file info for file number %d

Error message

error retrieving file info for file number %d

What it means

This is a fatal panic raised by getFileInfoOrPanic when os.Lstat fails to stat a block file (e.g. blockfile_000000) in the ledger's block storage directory. It means the file on disk is missing or unreadable even though the manager expected it to exist (typically referenced by blockfilesInfo or a fs scan). constructBlockfilesInfo/syncBlockfilesInfoFromFS call it while scanning the chains dir.

Source

Thrown at common/ledger/blkstorage/blockfile_helper.go:168

			return -1, err
		}
		if fileNum > biggestFileNum {
			biggestFileNum = fileNum
		}
	}
	logger.Debugf("retrieveLastFileSuffix() - biggestFileNum = %d", biggestFileNum)
	return biggestFileNum, err
}

func isBlockFileName(name string) bool {
	return strings.HasPrefix(name, blockfilePrefix)
}

func getFileInfoOrPanic(rootDir string, fileNum int) os.FileInfo {
	filePath := deriveBlockfilePath(rootDir, fileNum)
	fileInfo, err := os.Lstat(filePath)
	if err != nil {
		panic(errors.Wrapf(err, "error retrieving file info for file number %d", fileNum))
	}
	return fileInfo
}

func loadBootstrappingSnapshotInfo(rootDir string) (*BootstrappingSnapshotInfo, error) {
	bsiBytes, err := os.ReadFile(filepath.Join(rootDir, bootstrappingSnapshotInfoFile))
	if os.IsNotExist(err) {
		return nil, nil
	}
	if err != nil {
		return nil, errors.Wrapf(err, "error while reading bootstrappingSnapshotInfo file")
	}
	bsi := &BootstrappingSnapshotInfo{}
	if err := proto.Unmarshal(bsiBytes, bsi); err != nil {
		return nil, errors.Wrapf(err, "error while unmarshalling bootstrappingSnapshotInfo")
	}
	return bsi, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Restore the missing block file from backup (or a snapshot) so Lstat succeeds
  2. Check file permissions/ownership of the ledger's block storage dir and correct them (chown/chmod)
  3. If the ledger data is disposable, remove the ledger dir (and index DB) so it is re-created on peer start
  4. Verify the filesystem is healthy/mounted (dmesg, df) if Lstat fails with I/O errors

Example fix

// before: blindly trusting the DB's latestFileNumber after a partial copy
// after: sync DB info from FS before opening, or restore files:
// rsync -a backup/ledgersData/chains/mychannel/ /var/hyperledger/production/ledgersData/chains/mychannel/
Defensive patterns

Strategy: validation

Validate before calling

// before peer start / external checks
filePath := filepath.Join(rootDir, fmt.Sprintf("blockfile_%06d", fileNum))
if _, err := os.Lstat(filePath); err != nil {
    return fmt.Errorf("block file %s missing or unreadable: %w", filePath, err)
}

Type guard

func blockFileExists(rootDir string, fileNum int) bool {
    _, err := os.Lstat(deriveBlockfilePath(rootDir, fileNum))
    return err == nil
}

Try / catch

// Go: the library panics; recover at manager-construction boundary
func safeNewBlockStore(...) (s *BlockStore, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("blockstore init failed: %v", r)
        }
    }()
    return newBlockStore(...)
}

Prevention

When it happens

Trigger: os.Lstat returns any error (permission denied, I/O error, race deletion) on a derived block file path during blockfilesInfo construction/sync; a block file referenced by the DB is missing from the filesystem.

Common situations: Files deleted manually or by cleanup scripts while the ledger exists in the index DB; permissions changed on /var/hyperledger/production; NFS mount issues; running peer as wrong user after restore from backup.

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/997a555b3274385a. Report an issue: GitHub.