canopy-network/canopy · error · ErrStoreGet

quorum certificate not found

Error message

quorum certificate not found

What it means

Indexer.getQC returns "quorum certificate not found" (wrapped by ErrStoreGet) when the DB lookup for the QC at the given height returns zero bytes. It means no quorum certificate exists in the indexer for that height.

Source

Thrown at store/indexer.go:869

	}
	height := binary.BigEndian.Uint64(segments[2])
	return &lib.Checkpoint{
		Height:    height,
		BlockHash: value,
	}, nil
}

// HELPER CODE BELOW

// getQC() gets the QC bytes from the DB and converts it into a QC object
func (t *Indexer) getQC(heightKey []byte) (*lib.QuorumCertificate, lib.ErrorI) {
	// get from db
	bz, err := t.db.Get(heightKey)
	if err != nil {
		return nil, err
	}
	if len(bz) == 0 {
		return nil, ErrStoreGet(errors.New("quorum certificate not found"))
	}
	// convert to QC object
	ptr := new(lib.QuorumCertificate)
	if err = lib.Unmarshal(bz, ptr); err != nil {
		return nil, err
	}
	return ptr, nil
}

// getBlock() gets the block bytes from the DB and converts it into a filled BlockResult object including the transactions
func (t *Indexer) getBlock(hashKey []byte, transactions bool) (*lib.BlockResult, lib.ErrorI) {
	bz, err := t.db.Get(hashKey)
	if err != nil {
		return nil, err
	}
	if len(bz) == 0 {
		return nil, ErrStoreGet(errors.New("block not found"))
	}

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Check the height against the node's latest finalized height before querying
  2. Wait/retry until the node has finalized that height
  3. Verify node sync and data retention if the height should be available

Example fix

// before
qc, _ := idx.GetQCByHeight(h) // may not exist yet
// after
qc, err := idx.GetQCByHeight(h)
if err != nil && strings.Contains(err.Error(), "quorum certificate not found") {
	return pollLater(h) // retry after finalization
}
Defensive patterns

Strategy: retry

Validate before calling

latest := idx.GetLatestHeight()
if height > latest { return errors.New("height not yet finalized") }

Try / catch

qc, errI := idx.GetQCByHeight(height)
if errI != nil {
	if strings.Contains(errI.Error(), "quorum certificate not found") {
		return waitForFinalization(height) // poll with backoff
	}
	return nil, errI
}

Prevention

When it happens

Trigger: GetQCByHeight called with a height above the latest finalized height, below the pruning horizon, or on a node that never stored the QC for that height.

Common situations: Polling a height before the node finalizes it; querying after pruning; pointing a client at a lagging or fresh (unsynced) node.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/fbd5c7f5506c26c5. Report an issue: GitHub.