hyperledger/fabric · error

error discarding [%d] bytes

Error message

error discarding [%d] bytes

What it means

Wraps the bufio.Reader.Discard error when skipping the varint bytes representing the block size. Discard fails only on an I/O error or negative byte count, since the code has already verified via Peek that n bytes are buffered. This indicates a low-level read failure at the moment of consumption.

Source

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

	}
	length, n := protowire.ConsumeVarint(lenBytes)
	if n <= 0 {
		// proto.DecodeVarint did not consume any byte at all which means that the bytes
		// representing the size of the block are partial bytes
		if !moreContentAvailable {
			return nil, nil, ErrUnexpectedEndOfBlockfile
		}
		panic(errors.Errorf("Error in decoding varint bytes [%#v]", lenBytes))
	}
	bytesExpected := int64(n) + int64(length)
	if bytesExpected > remainingBytes {
		logger.Debugf("At least [%d] bytes expected. Remaining bytes = [%d]. Returning with error [%s]",
			bytesExpected, remainingBytes, ErrUnexpectedEndOfBlockfile)
		return nil, nil, ErrUnexpectedEndOfBlockfile
	}
	// skip the bytes representing the block size
	if _, err = s.reader.Discard(n); err != nil {
		return nil, nil, errors.Wrapf(err, "error discarding [%d] bytes", n)
	}
	blockBytes := make([]byte, length)
	if _, err = io.ReadAtLeast(s.reader, blockBytes, int(length)); err != nil {
		logger.Errorf("Error reading [%d] bytes from file number [%d], error: %s", length, s.fileNum, err)
		return nil, nil, errors.Wrapf(err, "error reading [%d] bytes from file number [%d]", length, s.fileNum)
	}
	blockPlacementInfo := &blockPlacementInfo{
		fileNum:          s.fileNum,
		blockStartOffset: s.currentOffset,
		blockBytesOffset: s.currentOffset + int64(n),
	}
	s.currentOffset += int64(n) + int64(length)
	logger.Debugf("Returning blockbytes - length=[%d], placementInfo={%s}", len(blockBytes), blockPlacementInfo)
	return blockBytes, blockPlacementInfo, nil
}

func (s *blockfileStream) close() error {
	return errors.WithStack(s.file.Close())

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the wrapped OS error and check storage health
  2. Ensure nothing external truncates or replaces blockfiles while the peer reads them
  3. Reopen the block stream and retry from the last known-good offset
  4. If corruption is suspected, restore the file from backup or re-sync from peers
Defensive patterns

Strategy: retry

Try / catch

blk, err := stream.nextBlockBytes()
if err != nil {
    if isTransientIO(errors.Cause(err)) {
        return reopenStreamAndRetry(offset)
    }
    return err
}

Prevention

When it happens

Trigger: nextBlockBytesAndPlacementInfo calls s.reader.Discard(n) after a successful Peek; failure means an underlying I/O error or an inconsistent buffer state (e.g. file changed between Peek and Discard).

Common situations: Disk I/O errors; file truncated/replaced between the Peek and Discard calls by an external process; descriptor issues on network-backed storage.

Related errors


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