hyperledger/fabric · critical

cannot get create BlockPuller

Error message

cannot get create BlockPuller

What it means

Synchronizer.synchronize asks the BlockPullerFactory to create a BlockPuller used to fetch blocks from remote consenters. If creation fails (typically because the local node cannot determine its position/height or crypto/dialer configuration is unusable), synchronization aborts wrapped with this message.

Source

Thrown at orderer/consensus/smartbft/synchronizer.go:85

		},
	}
}

func (s *Synchronizer) getViewMetadataLastConfigSqnFromBlock(block *cb.Block) (*smartbftprotos.ViewMetadata, uint64) {
	viewMetadata, err := getViewMetadataFromBlock(block)
	if err != nil {
		return nil, 0
	}

	lastConfigSqn := s.Support.Sequence()

	return viewMetadata, lastConfigSqn
}

func (s *Synchronizer) synchronize() (*types.Decision, error) {
	blockPuller, err := s.BlockPullerFactory.CreateBlockPuller(s.Support, s.ClusterDialer, s.LocalConfigCluster, s.CryptoProvider)
	if err != nil {
		return nil, errors.Wrap(err, "cannot get create BlockPuller")
	}
	defer blockPuller.Close()

	heightByEndpoint, _, err := blockPuller.HeightsByEndpoints()
	if err != nil {
		return nil, errors.Wrap(err, "cannot get HeightsByEndpoints")
	}

	s.Logger.Infof("HeightsByEndpoints: %v", heightByEndpoint)

	if len(heightByEndpoint) == 0 {
		return nil, errors.New("no cluster members to synchronize with")
	}

	var heights []uint64
	for _, value := range heightByEndpoint {
		heights = append(heights, value)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify General.TLS and Cluster settings: correct server/client certs, root CAs, and that the orderer's TLS cert is listed in the channel's consenters.
  2. Confirm the orderer is part of the channel consenter set (its certificate/tls SAN matches an entry in the channel config).
  3. Test network reachability and DNS to the other consenters' cluster ports (e.g. 7051/9051) from this node.
  4. Inspect the wrapped inner error in the orderer logs to pinpoint whether it is crypto, dialer, or config-block related; fix that root cause and retry sync.
  5. Re-join the node to the channel with a valid config block if it was never added as a consenter.

Example fix

# before
General:
  TLS:
    Enabled: true
    RootCAs: [/wrong/ca.pem]

# after
General:
  TLS:
    Enabled: true
    Certificate: /path/tls/server.crt
    PrivateKey: /path/tls/server.key
    RootCAs: [/correct/org-ca.pem]
Cluster:
  ServerCertificate: /path/tls/server.crt
  ClientCertificate: /path/tls/server.crt
  RootCAs: [/correct/org-ca.pem]
Defensive patterns

Strategy: retry

Validate before calling

// before triggering sync, verify puller prerequisites
if _, err := os.Stat(tlsCert); err != nil {
    return fmt.Errorf("cluster TLS cert missing: %w", err)
}
if !consenterCertInChannelConfig(localTLSCert, channelID) {
    return fmt.Errorf("node TLS cert not in consenter set of %s", channelID)
}

Try / catch

decision, err := synchronizer.Sync()
if err != nil && strings.Contains(err.Error(), "cannot get create BlockPuller") {
    // check TLS/consenter config, then retry with backoff
    fixClusterTLSIfMisconfigured()
    return retryWithBackoff(synchronizer.Sync)
}

Prevention

When it happens

Trigger: Sync is triggered (e.g. on chain start or when falling behind) but CreateBlockPuller fails — usually due to missing/invalid cluster TLS configuration, inability to self-identify in the consenters list, or failing to read the latest config block.

Common situations: Wrong cluster TLS root CAs/certs in orderer config; the node's TLS cert not matching any consenter in the channel; cluster endpoints unreachable due to firewall/DNS; freshly joined node with a config block that does not include it as consenter.

Related errors


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