{"record":{"id":"7bf7cb836e254ad9","repo":"hyperledger/fabric","slug":"cannot-get-create-blockpuller-7bf7cb","errorCode":null,"errorMessage":"cannot get create BlockPuller","messagePattern":"cannot get create BlockPuller","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/synchronizer_bft.go","lineNumber":135,"sourceCode":"\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to get any blocks from SyncBuffer\")\n\t}\n\n\tdecision := s.BlockToDecision(lastPulledBlock)\n\ts.Logger.Infof(\"Returning decision from block [%d], decision: %+v\", lastPulledBlock.GetHeader().GetNumber(), decision)\n\treturn decision, nil\n}\n\n// detectTargetHeight probes remote endpoints and detects what is the target height this node needs to reach. It also\n// detects the self-endpoint.\n//\n// In BFT it is highly recommended that the channel/orderer-endpoints (for delivery & broadcast) map 1:1 to the\n// channel/orderers/consenters (for cluster consensus), that is, every consenter should be represented by a\n// delivery endpoint. This important for Sync to work properly.\nfunc (s *BFTSynchronizer) detectTargetHeight() (uint64, string, error) {\n\tblockPuller, err := s.BlockPullerFactory.CreateBlockPuller(s.Support, s.ClusterDialer, s.LocalConfigCluster, s.CryptoProvider)\n\tif err != nil {\n\t\treturn 0, \"\", errors.Wrap(err, \"cannot get create BlockPuller\")\n\t}\n\tdefer blockPuller.Close()\n\n\theightByEndpoint, myEndpoint, err := blockPuller.HeightsByEndpoints()\n\tif err != nil {\n\t\treturn 0, \"\", errors.Wrap(err, \"cannot get HeightsByEndpoints\")\n\t}\n\n\ts.Logger.Infof(\"HeightsByEndpoints: %+v, my endpoint: %s\", heightByEndpoint, myEndpoint)\n\n\tdelete(heightByEndpoint, myEndpoint)\n\tvar heights []uint64\n\tfor _, value := range heightByEndpoint {\n\t\theights = append(heights, value)\n\t}\n\n\tif len(heights) == 0 {\n\t\treturn 0, \"\", errors.New(\"no cluster members to synchronize with\")","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/synchronizer_bft.go#L117-L153","documentation":"Raised in BFTSynchronizer.detectTargetHeight when s.BlockPullerFactory.CreateBlockPuller(...) returns an error. The BlockPuller is the client used to probe cluster endpoints and pull blocks; creation failures mean the puller could not even be constructed — usually TLS material or dialer configuration problems, before any network call is attempted.","triggerScenarios":"CreateBlockPuller fails with invalid cluster TLS config (missing/invalid cert/key files), predicate dialer misconfiguration, or crypto provider errors — invoked from synchronize during Sync.","commonSituations":"Bad paths in orderer.yaml cluster TLS settings; unreadable certificate files; wrong SAN/hostname setup; software version mismatch producing incompatible puller configuration.","solutions":["Fix the underlying error returned by CreateBlockPuller (it is wrapped — read the inner message)","Verify cluster.clientCertificate/clientPrivateKey files exist and are readable by the orderer process","Confirm the TLS CA certificate for remote orderers is correctly configured in the channel config","Validate orderer.yaml cluster section against a known-good template"],"exampleFix":"// before\ncluster:\n  serverCertificate:\n    File: /nonexistent/tls.crt\n// after\ncluster:\n  serverCertificate:\n    File: /var/hyperledger/orderer/tls/server.crt\n  serverPrivateKey:\n    File: /var/hyperledger/orderer/tls/server.key","handlingStrategy":"validation","validationCode":"// Run before starting the orderer / creating the puller\nfor _, f := range []string{cluster.ServerCertificate.File, cluster.ServerPrivateKey.File} {\n    if fi, err := os.Stat(f); err != nil || fi.IsDir() {\n        log.Fatalf(\"cluster TLS file missing or unreadable: %s\", f)\n    }\n}","typeGuard":null,"tryCatchPattern":"resp := bftSynchronizer.Sync()\n// puller creation is a config error, not transient: detect and stop retrying\nif syncFailed(resp) && pullerCreationFailedInLogs() {\n    alertOperator(\"fix cluster TLS configuration; retry will not help\")\n}","preventionTips":["Mount TLS secrets at fixed paths and verify with a startup health check","Check file permissions for the orderer process user","Generate certs with SANs matching configured hostnames","Test CreateBlockPuller paths in CI with production-like config"],"tags":["configuration","tls","smartbft","fabric"],"backgroundTag":"invalid-cluster-tls-config","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"}