{"record":{"id":"88c9f5f4eb34237f","repo":"hyperledger/fabric","slug":"cannot-get-create-blockpuller","errorCode":null,"errorMessage":"cannot get create BlockPuller","messagePattern":"cannot get create BlockPuller","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"orderer/consensus/smartbft/synchronizer.go","lineNumber":85,"sourceCode":"\t\t},\n\t}\n}\n\nfunc (s *Synchronizer) getViewMetadataLastConfigSqnFromBlock(block *cb.Block) (*smartbftprotos.ViewMetadata, uint64) {\n\tviewMetadata, err := getViewMetadataFromBlock(block)\n\tif err != nil {\n\t\treturn nil, 0\n\t}\n\n\tlastConfigSqn := s.Support.Sequence()\n\n\treturn viewMetadata, lastConfigSqn\n}\n\nfunc (s *Synchronizer) synchronize() (*types.Decision, error) {\n\tblockPuller, err := s.BlockPullerFactory.CreateBlockPuller(s.Support, s.ClusterDialer, s.LocalConfigCluster, s.CryptoProvider)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"cannot get create BlockPuller\")\n\t}\n\tdefer blockPuller.Close()\n\n\theightByEndpoint, _, err := blockPuller.HeightsByEndpoints()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"cannot get HeightsByEndpoints\")\n\t}\n\n\ts.Logger.Infof(\"HeightsByEndpoints: %v\", heightByEndpoint)\n\n\tif len(heightByEndpoint) == 0 {\n\t\treturn nil, errors.New(\"no cluster members to synchronize with\")\n\t}\n\n\tvar heights []uint64\n\tfor _, value := range heightByEndpoint {\n\t\theights = append(heights, value)\n\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/synchronizer.go#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Confirm the orderer is part of the channel consenter set (its certificate/tls SAN matches an entry in the channel config).","Test network reachability and DNS to the other consenters' cluster ports (e.g. 7051/9051) from this node.","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.","Re-join the node to the channel with a valid config block if it was never added as a consenter."],"exampleFix":"# before\nGeneral:\n  TLS:\n    Enabled: true\n    RootCAs: [/wrong/ca.pem]\n\n# after\nGeneral:\n  TLS:\n    Enabled: true\n    Certificate: /path/tls/server.crt\n    PrivateKey: /path/tls/server.key\n    RootCAs: [/correct/org-ca.pem]\nCluster:\n  ServerCertificate: /path/tls/server.crt\n  ClientCertificate: /path/tls/server.crt\n  RootCAs: [/correct/org-ca.pem]","handlingStrategy":"retry","validationCode":"// before triggering sync, verify puller prerequisites\nif _, err := os.Stat(tlsCert); err != nil {\n    return fmt.Errorf(\"cluster TLS cert missing: %w\", err)\n}\nif !consenterCertInChannelConfig(localTLSCert, channelID) {\n    return fmt.Errorf(\"node TLS cert not in consenter set of %s\", channelID)\n}","typeGuard":null,"tryCatchPattern":"decision, err := synchronizer.Sync()\nif err != nil && strings.Contains(err.Error(), \"cannot get create BlockPuller\") {\n    // check TLS/consenter config, then retry with backoff\n    fixClusterTLSIfMisconfigured()\n    return retryWithBackoff(synchronizer.Sync)\n}","preventionTips":["Double-check Cluster and General.TLS cert paths, root CAs, and SANs in orderer.yaml.","Ensure the orderer's TLS certificate is present in the channel's consenter set before starting sync-dependent flows.","Test DNS/firewall reachability to all consenter cluster ports from each node.","Read the wrapped inner error for the precise root cause (crypto vs dial vs config block).","Re-join nodes with a valid config block when consenter membership changed."],"tags":["hyperledger-fabric","smartbft","sync","block-puller","tls"],"backgroundTag":"block-puller-creation-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}