{"record":{"id":"3c1cea36cf028d24","repo":"hyperledger/fabric","slug":"no-block-header","errorCode":null,"errorMessage":"no block header","messagePattern":"no block header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/default_validation.go","lineNumber":64,"sourceCode":"}\n\nfunc (v *DefaultValidation) Validate(block *common.Block, namespace string, txPosition int, actionPosition int, contextData ...validation.ContextDatum) error {\n\tif len(contextData) == 0 {\n\t\tlogger.Panicf(\"Expected to receive policy bytes in context data\")\n\t}\n\n\tserializedPolicy, isSerializedPolicy := contextData[0].(vp.SerializedPolicy)\n\tif !isSerializedPolicy {\n\t\tlogger.Panicf(\"Expected to receive a serialized policy in the first context data\")\n\t}\n\tif block == nil || block.Data == nil {\n\t\treturn errors.New(\"empty block\")\n\t}\n\tif txPosition >= len(block.Data.Data) {\n\t\treturn errors.Errorf(\"block has only %d transactions, but requested tx at position %d\", len(block.Data.Data), txPosition)\n\t}\n\tif block.Header == nil {\n\t\treturn errors.Errorf(\"no block header\")\n\t}\n\n\tvar err error\n\tswitch {\n\tcase v.Capabilities.V2_0Validation():\n\t\terr = v.TxValidatorV2_0.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes())\n\n\tcase v.Capabilities.V1_3Validation():\n\t\terr = v.TxValidatorV1_3.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes())\n\n\tcase v.Capabilities.V1_2Validation():\n\t\tfallthrough\n\n\tdefault:\n\t\terr = v.TxValidatorV1_2.Validate(block, namespace, txPosition, actionPosition, serializedPolicy.Bytes())\n\t}\n\n\tlogger.Debugf(\"block %d, namespace: %s, tx %d validation results is: %v\", block.Header.Number, namespace, txPosition, err)","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/default_validation.go#L46-L82","documentation":"The builtin validation plugin validates block.Header before evaluating transactions, since header data (number, data hash) is needed by downstream validators. It returns 'no block header' when block.Header is nil, meaning the block lacks the header required for validation.","triggerScenarios":"Validate (committer path, TestErrorConversion, TestValidateBadInput) is called with a block whose Header field is nil — fabricated blocks in tests, or a deserialization/storage failure that dropped the header.","commonSituations":"Test fixtures constructing &common.Block{} without a Header; corrupted block store returning partial blocks after crash; custom block producers omitting the header; protobuf unmarshal errors silently yielding empty header fields.","solutions":["Ensure every block passed to Validate has a non-nil common.BlockHeader with Number and DataHash set","Check block storage health; rebuild ledger databases (peer node rebuild-dbs) if blocks come back partially formed","Fix the test harness or custom block source to populate the header","If unmarshaling blocks, verify the protobuf payload decodes fully and log unmarshal errors instead of ignoring them"],"exampleFix":"// before\nblock := &common.Block{Data: &common.BlockData{Data: [][]byte{env}}}\nerr := v.Validate(block, ns, 0, 0, policy) // no block header\n// after\nblock := &common.Block{\n    Header: &common.BlockHeader{Number: 5, DataHash: dataHash},\n    Data:   &common.BlockData{Data: [][]byte{env}},\n}\nerr := v.Validate(block, ns, 0, 0, policy)","handlingStrategy":"validation","validationCode":"func ensureHeader(b *common.Block) error {\n    if b == nil || b.Header == nil {\n        return errors.New(\"block missing header; cannot validate\")\n    }\n    if len(b.Header.DataHash) == 0 {\n        return errors.New(\"block header has empty DataHash\")\n    }\n    return nil\n}","typeGuard":"func hasHeader(b *common.Block) bool {\n    return b != nil && b.Header != nil && len(b.Header.DataHash) > 0\n}","tryCatchPattern":"if err := v.Validate(block, ns, txPos, actionPos, policy); err != nil {\n    if err.Error() == \"no block header\" {\n        logger.Errorf(\"block %d arrived without header; check storage\", num)\n    }\n    return err\n}","preventionTips":["Always populate BlockHeader in test fixtures","Fail loudly on protobuf unmarshal errors for blocks","Rebuild ledger DBs when storage returns partial blocks","Verify block hashes at ingest from ordering service"],"tags":["fabric","validation-plugin","block-validation","missing-header","committer"],"backgroundTag":"missing-block-header","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"}