hyperledger/fabric · critical
transaction %d in block %d has skipped validation
Error message
transaction %d in block %d has skipped validation
What it means
After validating a block, the validator asserts that every transaction received a validation flag. If any transaction still has TxValidationCode_NOT_VALIDATED, internal bookkeeping failed, so the whole block validation returns this error instead of committing a partially validated block.
Source
Thrown at core/committer/txvalidator/v14/validator.go:244
}
// Initialize metadata structure
protoutil.InitBlockMetadata(block)
block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsfltr
elapsedValidation := time.Since(startValidation) / time.Millisecond // duration in ms
logger.Infof("[%s] Validated block [%d] in %dms", v.ChannelID, block.Header.Number, elapsedValidation)
return nil
}
// allValidated returns error if some of the validation flags have not been set
// during validation
func (v *TxValidator) allValidated(txsfltr txflags.ValidationFlags, block *common.Block) error {
for id, f := range txsfltr {
if peer.TxValidationCode(f) == peer.TxValidationCode_NOT_VALIDATED {
return errors.Errorf("transaction %d in block %d has skipped validation", id, block.Header.Number)
}
}
return nil
}
func markTXIdDuplicates(txids []string, txsfltr txflags.ValidationFlags) {
txidMap := make(map[string]struct{})
for id, txid := range txids {
if txid == "" {
continue
}
_, in := txidMap[txid]
if in {
logger.Error("Duplicate txid", txid, "found, skipping")
txsfltr.SetFlag(id, peer.TxValidationCode_DUPLICATE_TXID)View on GitHub (pinned to 2736b63f8f)
Solutions
- Identify which validator (VSCC plugin) handled the transaction and why it didn't set a flag; check peer logs for preceding errors
- Fix or replace the custom validation plugin so it always returns a validation code
- Upgrade the peer to the latest patch release in case of a known validator bug
- Isolate the offending block/transaction and reprocess or refetch the block from the ordering service
Example fix
// before: plugin returns without setting code
func (p *MyPlugin) Validate(...) error { if bad { return errors.New("x") } ... }
// after
// return a proper validation code via the common errors mechanism
return errors.WithCommonValidationCode(errors.New("x")) Defensive patterns
Strategy: type-guard
Validate before calling
// after custom validation, verify all flags are set
for _, f := range txsfltr {
if peer.TxValidationCode(f) == peer.TxValidationCode_NOT_VALIDATED {
return errors.New("unset validation flag")
}
} Type guard
func allFlagsSet(flags txflags.ValidationFlags) bool {
for _, f := range flags {
if peer.TxValidationCode(f) == peer.TxValidationCode_NOT_VALIDATED { return false }
}
return true
} Try / catch
if err := validator.Validate(block); err != nil && strings.Contains(err.Error(), "has skipped validation") {
// halt commit pipeline, inspect plugin/validator, do not commit the block
} Prevention
- Custom validators must always set a validation code before returning
- Unit-test plugin behavior for every error path
- Upgrade peers to patched Fabric releases
- Validate blocks against a reference validator in staging
When it happens
Trigger: allValidated (called from Validate) finds a flag in txsfltr equal to NOT_VALIDATED after the per-transaction validation loop — a validator path failed to set a commit/validation code for that transaction.
Common situations: Custom validation plugin returning without setting a validation code; internal Fabric bug in a validation path; corrupted/malformed block causing a validation branch to skip flag assignment.
Related errors
- error compiling regexp: %s
- failed to extract envelope from the block
- %s is mandatory and cannot be empty
- enrollment certificate isn't a valid PEM block
- failed to decode PEM block from %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b33790a7e44c8383.
Report an issue: GitHub.