hyperledger/fabric · error

failed to look up the ledger for Channel %s

Error message

failed to look up the ledger for Channel %s

What it means

GetTransactionByID could not resolve the channel to a ledger on this peer, so the transaction ID cannot be looked up. GetLedger(chid) returned nil; this is a channel-existence guard, distinct from the subsequent 'GetTransactionByID failed' wrap which indicates the tx itself was not found in an existing ledger.

Source

Thrown at core/endorser/support.go:83

	}
	return lgr.NewTxSimulator(txid)
}

// GetHistoryQueryExecutor gives handle to a history query executor for the
// specified ledger
func (s *SupportImpl) GetHistoryQueryExecutor(ledgername string) (ledger.HistoryQueryExecutor, error) {
	lgr := s.Peer.GetLedger(ledgername)
	if lgr == nil {
		return nil, errors.Errorf("Channel does not exist: %s", ledgername)
	}
	return lgr.NewHistoryQueryExecutor()
}

// GetTransactionByID retrieves a transaction by id
func (s *SupportImpl) GetTransactionByID(chid, txID string) (*pb.ProcessedTransaction, error) {
	lgr := s.Peer.GetLedger(chid)
	if lgr == nil {
		return nil, errors.Errorf("failed to look up the ledger for Channel %s", chid)
	}
	tx, err := lgr.GetTransactionByID(txID)
	if err != nil {
		return nil, errors.WithMessage(err, "GetTransactionByID failed")
	}
	return tx, nil
}

// GetLedgerHeight returns ledger height for given channelID
func (s *SupportImpl) GetLedgerHeight(channelID string) (uint64, error) {
	lgr := s.Peer.GetLedger(channelID)
	if lgr == nil {
		return 0, errors.Errorf("failed to look up the ledger for Channel %s", channelID)
	}

	info, err := lgr.GetBlockchainInfo()
	if err != nil {
		return 0, errors.Wrap(err, fmt.Sprintf("failed to obtain information for Channel %s", channelID))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Join the peer to the channel or route the request to a peer on that channel
  2. Verify the channel ID used by the client matches the deployed channel
  3. If the ledger exists but the tx is missing, look for the separate 'GetTransactionByID failed' wrap instead (tx genuinely not committed)
  4. Check peer startup logs for channel open failures
Defensive patterns

Strategy: validation

Validate before calling

if (!await peerJoinedChannel(peer, chid)) throw new Error(`query tx ${txID} on a peer joined to ${chid}`);

Try / catch

try {
  return await getTransactionById(chid, txID);
} catch (e) {
  if (e.message.includes('failed to look up the ledger for Channel')) {
    throw new Error(`peer has no ledger for ${chid}; wrong peer or channel`, { cause: e });
  }
  if (e.message.includes('GetTransactionByID failed')) {
    throw new Error('transaction not found in ledger (may not be committed yet)', { cause: e });
  }
  throw e;
}

Prevention

When it happens

Trigger: Support.GetTransactionByID(chid, txID) invoked (e.g. from the endorser validating duplicate txids) with a channel the peer does not have a ledger for.

Common situations: Duplicate-txid check during endorsement on a peer not joined to the proposal's channel; client querying transaction status against the wrong peer; channel name mismatch between SDK and network.

Related errors


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