hyperledger/fabric · error
failed re-marshaling envelope: %v
Error message
failed re-marshaling envelope: %v
What it means
During well-formedness verification the Envelope is re-marshaled with proto.Marshal(env) to compare against the original raw bytes. If proto.Marshal returns an error (e.g. an invalid required field or a marshal failure inside the payload submessage), the function surfaces it wrapped as 'failed re-marshaling envelope: %v'. This guards against envelopes that unmarshal but cannot round-trip deterministically.
Source
Thrown at protoutil/blockutils.go:343
}
for i, rawTx := range bd.Data {
env := &cb.Envelope{}
if err := proto.Unmarshal(rawTx, env); err != nil {
return fmt.Errorf("transaction %d is invalid: %v", i, err)
}
if len(env.Payload) == 0 {
return fmt.Errorf("transaction %d has no payload", i)
}
if len(env.Signature) == 0 {
return fmt.Errorf("transaction %d has no signature", i)
}
expected, err := proto.Marshal(env)
if err != nil {
return fmt.Errorf("failed re-marshaling envelope: %v", err)
}
if len(expected) < len(rawTx) {
return fmt.Errorf("transaction %d has %d trailing bytes", i, len(rawTx)-len(expected))
}
if !bytes.Equal(expected, rawTx) {
return fmt.Errorf("transaction %d (%s) does not match its raw form (%s)", i,
base64.StdEncoding.EncodeToString(expected), base64.StdEncoding.EncodeToString(rawTx))
}
}
return nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped %v cause to identify which field/submessage failed to marshal.
- Rebuild the envelope with the same protobuf library version (google.golang.org/protobuf) used by the rest of the network.
- Re-fetch or regenerate the block from a trusted source.
- If caused by unknown fields, re-marshal through a clean proto.Clone to canonicalize before hashing.
Example fix
// before: mixing github.com/golang/protobuf and google.golang.org/protobuf import "github.com/golang/protobuf/proto" // after import "google.golang.org/protobuf/proto"
Defensive patterns
Strategy: try-catch
Validate before calling
env := &cb.Envelope{}
if err := proto.Unmarshal(rawTx, env); err != nil { return err }
if _, err := proto.Marshal(env); err != nil {
return fmt.Errorf("envelope does not round-trip: %w", err)
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Printf("block verification panicked: %v", r)
}
}()
if err := protoutil.VerifyTransactionsAreWellFormed(block); err != nil {
return fmt.Errorf("malformed block rejected: %w", err)
} Prevention
- Use one protobuf runtime (google.golang.org/protobuf) consistently across the network.
- Keep .pb.go generated code in sync with the runtime version.
- Round-trip test envelopes (Marshal→Unmarshal→Marshal) in CI.
- Do not hand-edit serialized protobuf bytes.
When it happens
Trigger: BlockDataHash iterates block data, successfully unmarshals an Envelope, but proto.Marshal(env) fails — typically due to unknown/invalid fields or a marshal error deep inside Payload/ChannelHeader submessages.
Common situations: Blocks produced by a different protobuf runtime version with incompatible wire data; corrupted submessages that unmarshal leniently but fail strict re-marshal; hand-edited protobuf bytes in test fixtures.
Related errors
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ffb9d4a3d14ec3e7.
Report an issue: GitHub.