{"record":{"id":"2a5eb05f34929f9a","repo":"hyperledger/fabric","slug":"nil-block","errorCode":null,"errorMessage":"nil block","messagePattern":"nil block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/util.go","lineNumber":318,"sourceCode":"\t}\n\n\tformattedEndpointCriteria := make(map[string]any)\n\tformattedEndpointCriteria[\"Endpoint\"] = ep.Endpoint\n\tformattedEndpointCriteria[\"CAs\"] = formattedCAs\n\n\trawJSON, err := json.Marshal(formattedEndpointCriteria)\n\tif err != nil {\n\t\treturn fmt.Sprintf(\"{\\\"Endpoint\\\": \\\"%s\\\"}\", ep.Endpoint)\n\t}\n\n\treturn string(rawJSON)\n}\n\n// EndpointconfigFromConfigBlock retrieves TLS CA certificates and endpoints\n// from a config block.\nfunc EndpointconfigFromConfigBlock(block *common.Block, bccsp bccsp.BCCSP) ([]EndpointCriteria, error) {\n\tif block == nil {\n\t\treturn nil, errors.New(\"nil block\")\n\t}\n\tenvelopeConfig, err := protoutil.ExtractEnvelope(block, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, bccsp)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed extracting bundle from envelope\")\n\t}\n\tmsps, err := bundle.MSPManager().GetMSPs()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed obtaining MSPs from MSPManager\")\n\t}\n\tordererConfig, ok := bundle.OrdererConfig()\n\tif !ok {\n\t\treturn nil, errors.New(\"failed obtaining orderer config from bundle\")\n\t}","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/util.go#L300-L336","documentation":"EndpointconfigFromConfigBlock in orderer/common/cluster/util.go extracts TLS CA certificates and ordering endpoints from a config block. This error is returned when the *common.Block argument passed to it is nil. The library throws it as a defensive guard, since extracting an envelope from a nil block would otherwise panic with a nil pointer dereference.","triggerScenarios":"Calling cluster.EndpointconfigFromConfigBlock(nil, bccsp) directly, or indirectly when BlockPuller/EndpointconfigFromSupport passes a nil block — e.g., pullUntilTarget returned nil because the target block could not be pulled, or a caller passed the result of a failed block fetch without a nil check.","commonSituations":"BlockPuller fails to pull the target block (network/TLS issues, node not joined to the channel) and its nil result flows into endpoint extraction; a genesis/config block lookup returns nil on an empty or uninitialized ledger; chaincode or test code calls the API with an unset block variable.","solutions":["Check why the block was nil before the call: if it came from BlockPuller, inspect the puller's logs (TLS CA errors, endpoint unreachable) and fix the underlying pull failure.","Add an explicit nil check on the block before calling EndpointconfigFromConfigBlock and handle the empty case gracefully.","Ensure the local ledger actually contains the config block being requested (genesis block present; channel joined correctly).","Verify channel/TLS configuration so the puller can retrieve the config block from a valid orderer endpoint."],"exampleFix":"// before\nblock, _ := puller.PullBlock(targetSeq)\ncriteria, err := cluster.EndpointconfigFromConfigBlock(block, bccsp) // error: nil block\n// after\nblock, err := puller.PullBlock(targetSeq)\nif err != nil { return nil, errors.Wrap(err, \"failed pulling config block\") }\nif block == nil { return nil, errors.New(\"no config block available\") }\ncriteria, err := cluster.EndpointconfigFromConfigBlock(block, bccsp)","handlingStrategy":"type-guard","validationCode":"if block == nil || block.Header == nil {\n    return nil, errors.New(\"cannot extract endpoint config: no config block available\")\n}\ncriteria, err := cluster.EndpointconfigFromConfigBlock(block, bccsp)","typeGuard":"func isConfigBlockReady(b *common.Block) bool { return b != nil && b.Header != nil && b.Data != nil }\n// usage: if !isConfigBlockReady(block) { re-pull or abort }","tryCatchPattern":"criteria, err := cluster.EndpointconfigFromConfigBlock(block, bccsp)\nif err != nil {\n    if err.Error() == \"nil block\" {\n        // the puller failed upstream; re-pull the config block and retry once\n        block, perr := puller.PullBlock(targetSeq)\n        if perr == nil && block != nil { criteria, err = cluster.EndpointconfigFromConfigBlock(block, bccsp) }\n    }\n    if err != nil { return err }\n}","preventionTips":["Always check the error (not just the value) from PullBlock before using the returned block","Ensure the node is joined to the channel and the genesis block exists locally","Fix BlockPuller connectivity/TLS issues before downstream endpoint extraction","Initialize block variables to detected errors, never leave them as silently-nil values"],"tags":["hyperledger-fabric","orderer","nil-pointer","config-block"],"backgroundTag":"nil-block","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"}