hyperledger/fabric · error

properties is nil

Error message

properties is nil

What it means

validateStateInfoMessage requires StateInfo.Properties to be non-nil; Properties carries ledger height, chaincodes installed, and roles, which the discovery client needs to rank endorsers. Missing properties means the client cannot evaluate the peer for endorsement, so validation fails.

Source

Thrown at discovery/client/client.go:598

	if m == nil {
		return errors.New("membership is empty")
	}
	if am.Timestamp == nil {
		return errors.New("timestamp is nil")
	}
	return nil
}

func validateStateInfoMessage(message *gprotoext.SignedGossipMessage) error {
	si := message.GetStateInfo()
	if si == nil {
		return errors.New("message isn't a stateInfo message")
	}
	if si.Timestamp == nil {
		return errors.New("timestamp is nil")
	}
	if si.Properties == nil {
		return errors.New("properties is nil")
	}
	return nil
}

func validateInterests(interests ...*peer.ChaincodeInterest) error {
	if len(interests) == 0 {
		return errors.New("no chaincode interests given")
	}
	for _, interest := range interests {
		if interest == nil {
			return errors.New("chaincode interest is nil")
		}
		if err := InvocationChain(interest.Chaincodes).ValidateInvocationChain(); err != nil {
			return err
		}
	}
	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Wait until the peer finishes catching up its ledger, then retry discovery
  2. Upgrade the peer to a Fabric version compatible with the rest of the network
  3. Restart the peer so it regenerates StateInfo with Properties
  4. Retry discovery against a different, fully synced peer

Example fix

// before
peers, err := resp.ForChannel("mychannel")
// after
peers, err := resp.ForChannel("mychannel")
if err != nil && strings.Contains(err.Error(), "properties is nil") {
    logger.Warnf("peer state info lacks properties; peer ledger may not be synced yet")
    return retryDiscovery(ctx)
}
Defensive patterns

Strategy: validation

Validate before calling

func stateInfoHasProperties(m *gprotoext.SignedGossipMessage) bool {
    si := m.GetStateInfo()
    return si != nil && si.Properties != nil && si.Properties.LedgerHeight > 0
}

Type guard

func hasStateInfoProperties(m *gprotoext.SignedGossipMessage) bool {
    si := m.GetStateInfo()
    return si != nil && si.Properties != nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "properties is nil") {
    logger.Warnf("peer state info lacks properties; ledger may still be syncing")
    time.Sleep(backoff)
    return retryDiscovery(ctx)
}

Prevention

When it happens

Trigger: A discovery response StateInfo lacks Properties — the peer did not include its ledger/chaincode metadata in its state info, or the payload was truncated.

Common situations: Peer running a Fabric version whose StateInfo omits Properties; peer still initializing its ledger when queried; protobuf decode dropping the field due to corruption or version skew.

Related errors


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