{"record":{"id":"e80225ad45fbebd5","repo":"hyperledger/fabric","slug":"failed-to-retrieve-last-config-envelope","errorCode":null,"errorMessage":"failed to retrieve last config envelope","messagePattern":"failed to retrieve last config envelope","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/synchronizer_bft.go","lineNumber":190,"sourceCode":"\n\tif lenH < f+1 {\n\t\ts.Logger.Debugf(\"Returning %d\", heights[int(lenH)-1])\n\t\treturn heights[int(lenH)-1]\n\t}\n\ts.Logger.Debugf(\"Returning %d\", heights[f])\n\treturn heights[f]\n}\n\n// createBFTDeliverer creates and initializes the BFT block deliverer.\nfunc (s *BFTSynchronizer) createBFTDeliverer(startHeight uint64, myEndpoint string) (BFTBlockDeliverer, error) {\n\tlastBlock := s.Support.Block(startHeight - 1)\n\tlastConfigBlock, err := cluster.LastConfigBlock(lastBlock, s.Support)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to retrieve last config block\")\n\t}\n\tlastConfigEnv, err := deliverclient.ConfigFromBlock(lastConfigBlock)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to retrieve last config envelope\")\n\t}\n\n\tvar updatableVerifier deliverclient.CloneableUpdatableBlockVerifier\n\tupdatableVerifier, err = s.VerifierFactory.CreateBlockVerifier(lastConfigBlock, lastBlock, s.CryptoProvider, s.Logger)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to create BlockVerificationAssistant\")\n\t}\n\n\tclientConfig := s.ClusterDialer.Config // The cluster and block puller use slightly different options\n\tclientConfig.AsyncConnect = false\n\tclientConfig.SecOpts.VerifyCertificate = nil\n\n\t// The maximal amount of time to wait before retrying to connect.\n\tmaxRetryInterval := s.LocalConfigCluster.ReplicationRetryTimeout\n\t// The minimal amount of time to wait before retrying. The retry interval doubles after every unsuccessful attempt.\n\tminRetryInterval := maxRetryInterval / 50\n\t// The maximal duration of a Sync. After this time Sync returns with whatever it had pulled until that point.\n\tmaxRetryDuration := s.LocalConfigCluster.ReplicationPullTimeout * time.Duration(s.LocalConfigCluster.ReplicationMaxRetries)","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/synchronizer_bft.go#L172-L208","documentation":"createBFTDeliverer wraps a failure of deliverclient.ConfigFromBlock on the last config block: the config envelope could not be extracted/unmarshalled from that block, so the channel configuration needed for block verification is unreadable.","triggerScenarios":"Thrown at orderer/consensus/smartbft/synchronizer_bft.go:190 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the config block in the ledger is intact","Restore the ledger or re-sync from other cluster members"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}