hyperledger/fabric · error
only one commit notifications channel is allowed at a time
Error message
only one commit notifications channel is allowed at a time
What it means
CommitNotificationsChannel returns this error when a commit notifications channel already exists on the kvLedger and has not been released. Fabric allows only one active commit notification consumer at a time; the existing notifier must be closed (via the done channel) before a new one can be created.
Source
Thrown at core/ledger/kvledger/kv_ledger.go:968
}
type commitNotifier struct {
dataChannel chan *ledger.CommitNotification
doneChannel <-chan struct{}
}
// CommitNotificationsChannel returns a read-only channel on which ledger sends a `CommitNotification`
// when a block is committed. The CommitNotification contains entries for the transactions from the committed block,
// which are not malformed, carry a legitimate TxID, and in addition, are not marked as a duplicate transaction.
// The consumer can close the 'done' channel to signal that the notifications are no longer needed. This will cause the
// CommitNotifications channel to close. There is expected to be only one consumer at a time. The function returns error
// if already a CommitNotification channel is active.
func (l *kvLedger) CommitNotificationsChannel(done <-chan struct{}) (<-chan *ledger.CommitNotification, error) {
l.commitNotifierLock.Lock()
defer l.commitNotifierLock.Unlock()
if l.commitNotifier != nil {
return nil, errors.New("only one commit notifications channel is allowed at a time")
}
l.commitNotifier = &commitNotifier{
dataChannel: make(chan *ledger.CommitNotification, 10),
doneChannel: done,
}
return l.commitNotifier.dataChannel, nil
}
func (l *kvLedger) sendCommitNotification(blockNum uint64, txStatsInfo []*validation.TxStatInfo) {
l.commitNotifierLock.Lock()
defer l.commitNotifierLock.Unlock()
if l.commitNotifier == nil {
return
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the previous consumer signals its done channel before subscribing again
- Reuse the single existing notifications channel instead of creating a second one
- Fan out events internally: one subscriber broadcasts to multiple internal consumers
- Restart the peer/service if a notifier leaked due to a bug in an older version
Example fix
// before: two concurrent subscriptions
ch1, _ := ledger.CommitNotificationsChannel(done1)
ch2, _ := ledger.CommitNotificationsChannel(done2) // error
// after: one channel fanned out
ch, _ := ledger.CommitNotificationsChannel(done)
go func() { for n := range ch { fanout(n) } }() Defensive patterns
Strategy: type-guard
Validate before calling
// Guard before subscribing:
var mu sync.Mutex
var activeCh <-chan *ledger.CommitNotification
mu.Lock()
if activeCh != nil { mu.Unlock(); return activeCh, nil } // reuse existing
mu.Unlock() Type guard
func hasActiveNotifier(ch <-chan *ledger.CommitNotification) bool { return ch != nil } Try / catch
ch, err := ledger.CommitNotificationsChannel(done)
if err != nil && strings.Contains(err.Error(), "only one commit notifications channel") {
// reuse existing subscription or wait for previous done to close
<-previousDone
ch, err = ledger.CommitNotificationsChannel(done)
} Prevention
- Maintain a single process-wide commit notification consumer and fan out internally
- Always close the done channel when finished consuming
- Serialize subscription setup with a mutex in application code
When it happens
Trigger: Calling ledger.CommitNotificationsChannel(done) twice without closing/signalizing the first done channel (or without the first consumer finishing), leaving l.commitNotifier non-nil.
Common situations: An application or chaincode event service subscribes twice concurrently (e.g. double initialization, both a block listener and a custom service requesting notifications), or a leaked subscription never closes its done channel.
Related errors
- error decoding the block number
- error decoding the data hash
- error decoding the previous hash
- error decoding the length of block data
- error decoding the transaction envelope
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/e1b3af0c63b20e20.
Report an issue: GitHub.