hyperledger/fabric · error

error unmarshalling SignaturePolicyEnvelope

Error message

error unmarshalling SignaturePolicyEnvelope

What it means

UnmarshalSignaturePolicy wraps proto.Unmarshal failures for common.SignaturePolicyEnvelope bytes. It is returned when policy bytes are malformed, not a SignaturePolicyEnvelope, or the wrong serialization (e.g. YAML/JSON policy text instead of marshalled proto). Only parsing tooling (parseWritesetMetadata, info commands) calls it.

Source

Thrown at protoutil/unmarshalers.go:200

// UnmarshalKVRWSet unmarshals bytes to a KVRWSet
func UnmarshalKVRWSet(bytes []byte) (*kvrwset.KVRWSet, error) {
	rws := &kvrwset.KVRWSet{}
	err := proto.Unmarshal(bytes, rws)
	return rws, errors.Wrap(err, "error unmarshalling KVRWSet")
}

// UnmarshalHashedRWSet unmarshals bytes to a HashedRWSet
func UnmarshalHashedRWSet(bytes []byte) (*kvrwset.HashedRWSet, error) {
	hrws := &kvrwset.HashedRWSet{}
	err := proto.Unmarshal(bytes, hrws)
	return hrws, errors.Wrap(err, "error unmarshalling HashedRWSet")
}

// UnmarshalSignaturePolicy unmarshals bytes to a SignaturePolicyEnvelope
func UnmarshalSignaturePolicy(bytes []byte) (*common.SignaturePolicyEnvelope, error) {
	sp := &common.SignaturePolicyEnvelope{}
	err := proto.Unmarshal(bytes, sp)
	return sp, errors.Wrap(err, "error unmarshalling SignaturePolicyEnvelope")
}

// UnmarshalPayloadOrPanic unmarshals bytes to a Payload structure or panics
// on error
func UnmarshalPayloadOrPanic(encoded []byte) *common.Payload {
	payload, err := UnmarshalPayload(encoded)
	if err != nil {
		panic(err)
	}
	return payload
}

// UnmarshalEnvelopeOrPanic unmarshals bytes to an Envelope structure or panics
// on error
func UnmarshalEnvelopeOrPanic(encoded []byte) *common.Envelope {
	envelope, err := UnmarshalEnvelope(encoded)
	if err != nil {
		panic(err)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure the bytes are proto.Marshal output of a SignaturePolicyEnvelope, not a policy expression string (use cauthdsl/policy parsers for strings first)
  2. Check the policy bytes are non-empty before unmarshalling
  3. Re-marshal the policy with the same fabric-protos version if it came from an older network
  4. Validate the decoded envelope's identities/rules are sane before trusting it

Example fix

// before
sp, err := protoutil.UnmarshalSignaturePolicy([]byte("AND('Org1.peer')")) // string, not proto
// after
env, err := cauthdsl.FromString("AND('Org1.peer')")
spBytes, _ := proto.Marshal(env)
sp, err := protoutil.UnmarshalSignaturePolicy(spBytes)
Defensive patterns

Strategy: validation

Validate before calling

func validPolicyBytes(b []byte) bool {
    if len(b) == 0 { return false }
    sp, err := protoutil.UnmarshalSignaturePolicy(b)
    return err == nil && sp != nil && sp.Rule != nil
}

Type guard

func safeUnmarshalPolicy(b []byte) (sp *common.SignaturePolicyEnvelope, ok bool) {
    sp, err := protoutil.UnmarshalSignaturePolicy(b)
    return sp, err == nil && sp != nil
}

Try / catch

sp, err := protoutil.UnmarshalSignaturePolicy(policyBytes)
if err != nil {
    return nil, fmt.Errorf("policy bytes are not a marshalled SignaturePolicyEnvelope: %w", err)
}

Prevention

When it happens

Trigger: Calling UnmarshalSignaturePolicy on a policy definition string that was never proto-marshalled, empty bytes, policy bytes stored by an incompatible Fabric version, or truncated config values.

Common situations: Inspecting collection/lifecycle endorsement policies, CLI 'info' commands decoding policy metadata, or operators passing raw policy strings where marshalled bytes are expected.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/b5dc81dab33e97dc. Report an issue: GitHub.