hyperledger/fabric · error

create new lock based TxMgr failed: passed in nil ledger has

Error message

create new lock based TxMgr failed: passed in nil ledger hasher

What it means

NewLockBasedTxMgr requires a hash function from the ledger initializer to compute hashes for private-data and rwset handling. A nil HashFunc means the transaction manager cannot be constructed safely, so it fails fast.

Source

Thrown at core/ledger/kvledger/txmgmt/txmgr/lockbased_txmgr.go:97

	}
}

// Initializer captures the dependencies for tx manager
type Initializer struct {
	LedgerID            string
	DB                  *privacyenabledstate.DB
	StateListeners      []ledger.StateListener
	BtlPolicy           pvtdatapolicy.BTLPolicy
	BookkeepingProvider *bookkeeping.Provider
	CCInfoProvider      ledger.DeployedChaincodeInfoProvider
	CustomTxProcessors  map[common.HeaderType]ledger.CustomTxProcessor
	HashFunc            rwsetutil.HashFunc
}

// NewLockBasedTxMgr constructs a new instance of NewLockBasedTxMgr
func NewLockBasedTxMgr(initializer *Initializer) (*LockBasedTxMgr, error) {
	if initializer.HashFunc == nil {
		return nil, errors.New("create new lock based TxMgr failed: passed in nil ledger hasher")
	}

	if err := initializer.DB.Open(); err != nil {
		return nil, err
	}
	txmgr := &LockBasedTxMgr{
		ledgerid:       initializer.LedgerID,
		db:             initializer.DB,
		stateListeners: initializer.StateListeners,
		ccInfoProvider: initializer.CCInfoProvider,
		hashFunc:       initializer.HashFunc,
	}
	pvtstatePurgeMgr, err := pvtstatepurgemgmt.InstantiatePurgeMgr(
		initializer.LedgerID,
		initializer.DB,
		initializer.BtlPolicy,
		initializer.BookkeepingProvider,
	)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Provide a hash function in the Initializer, e.g. HashFunc: func(data []byte) ([]byte, error) { h := sha256.New(); h.Write(data); return h.Sum(nil), nil }.
  2. Use the peer's standard ledger initializer (ledgerUtil) which wires the hasher automatically.
  3. Update stale test harnesses to set HashFunc when constructing txmgmt.Initializer.
  4. If HashFunc became required in a version upgrade, port the setup code to the new Initializer contract.

Example fix

// before
initializer := &txmgr.Initializer{DB: db}
txmgr, err := txmgr.NewLockBasedTxMgr(initializer)
// after
initializer := &txmgr.Initializer{
  DB: db,
  HashFunc: func(data []byte) ([]byte, error) {
    h := sha256.New(); h.Write(data); return h.Sum(nil), nil
  },
}
txmgr, err := txmgr.NewLockBasedTxMgr(initializer)
Defensive patterns

Strategy: validation

Validate before calling

if initializer == nil || initializer.HashFunc == nil {
  return nil, errors.New("txmgr initializer requires a HashFunc")
}
txmgr, err := txmgr.NewLockBasedTxMgr(initializer)

Type guard

func initializerReady(i *txmgr.Initializer) bool {
  return i != nil && i.HashFunc != nil && i.DB != nil
}

Try / catch

txmgr, err := txmgr.NewLockBasedTxMgr(initializer)
if err != nil {
  return fmt.Errorf("tx manager init failed: %w", err)
}

Prevention

When it happens

Trigger: Calling NewLockBasedTxMgr with an Initializer whose HashFunc field is nil — typically in test harness setup (newTestHistoryEnv, initTxMgr) or custom ledger initializer code that omits the hasher.

Common situations: Test environments constructed without wiring a ledger hasher; refactoring where the Initializer struct gained the HashFunc field but existing setup code was not updated; custom peer extensions building their own Initializer.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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