hyperledger/fabric · error

error getting block file stat

Error message

error getting block file stat

What it means

Wraps the os.File.Stat error when nextBlockBytesAndPlacementInfo cannot determine the current size of the blockfile. File size is required to decide whether more content remains or the stream has hit end-of-file. Without a successful Stat the stream cannot safely continue reading.

Source

Thrown at common/ledger/blkstorage/block_stream.go:90

}

func (s *blockfileStream) nextBlockBytes() ([]byte, error) {
	blockBytes, _, err := s.nextBlockBytesAndPlacementInfo()
	return blockBytes, err
}

// nextBlockBytesAndPlacementInfo returns bytes for the next block
// along with the offset information in the block file.
// An error `ErrUnexpectedEndOfBlockfile` is returned if a partial written data is detected
// which is possible towards the tail of the file if a crash had taken place during appending of a block
func (s *blockfileStream) nextBlockBytesAndPlacementInfo() ([]byte, *blockPlacementInfo, error) {
	var lenBytes []byte
	var err error
	var fileInfo os.FileInfo
	moreContentAvailable := true

	if fileInfo, err = s.file.Stat(); err != nil {
		return nil, nil, errors.Wrapf(err, "error getting block file stat")
	}
	if s.currentOffset == fileInfo.Size() {
		logger.Debugf("Finished reading file number [%d]", s.fileNum)
		return nil, nil, nil
	}
	remainingBytes := fileInfo.Size() - s.currentOffset
	// Peek 8 or smaller number of bytes (if remaining bytes are less than 8)
	// Assumption is that a block size would be small enough to be represented in 8 bytes varint
	peekBytes := 8
	if remainingBytes < int64(peekBytes) {
		peekBytes = int(remainingBytes)
		moreContentAvailable = false
	}
	logger.Debugf("Remaining bytes=[%d], Going to peek [%d] bytes", remainingBytes, peekBytes)
	if lenBytes, err = s.reader.Peek(peekBytes); err != nil {
		return nil, nil, errors.Wrapf(err, "error peeking [%d] bytes from block file", peekBytes)
	}
	length, n := protowire.ConsumeVarint(lenBytes)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped OS error; ENOENT means the blockfile was deleted while being read
  2. Stop any external cleanup/rotation of ledger files while the peer is running
  3. Reopen the block stream (fresh newBlockfileStream) after restoring the file
  4. Check storage health if EIO is reported
Defensive patterns

Strategy: retry

Try / catch

var bs *blockStream
var err error
for attempt := 0; attempt < 3; attempt++ {
    bs, err = newBlockStream(rootDir, num, offset)
    if err == nil { break }
    if errors.Is(errors.Cause(err), os.ErrNotExist) { return restoreFile() }
    time.Sleep(backoff(attempt))
}

Prevention

When it happens

Trigger: nextBlockBytesAndPlacementInfo (via nextBlockBytes) calls s.file.Stat() and it fails — file descriptor closed, file deleted mid-stream, or I/O error.

Common situations: Ledger file removed/rotated underneath an open stream (cleanup job or manual rm); descriptor closed twice by a bug; storage errors on a failing disk or detached network volume.

Related errors


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