hyperledger/fabric · error

unknown or missing request type

Error message

unknown or missing request type

What it means

Returned by the discovery Service.dispatch when the query's request type has no registered dispatcher: either the query type field is unset/unknown (not one of the defined discovery.Query content types) or the query was routed to the wrong dispatcher table (local vs channel dispatchers only serve certain query types). The service cannot determine what the client is asking for.

Source

Thrown at discovery/service.go:126

		Data:      request.Payload,
		Signature: request.Signature,
		Identity:  identity,
	}); err != nil {
		logger.Warning("got query for channel", query.Channel, "from", addr, "but it isn't eligible:", err)
		return accessDenied
	}
	return s.dispatch(query)
}

func (s *Service) dispatch(q *discovery.Query) *discovery.QueryResult {
	dispatchers := s.channelDispatchers
	// Ensure local queries are routed only to channel-less dispatchers
	if q.Channel == "" {
		dispatchers = s.localDispatchers
	}
	dispatchQuery, exists := dispatchers[protoext.GetQueryType(q)]
	if !exists {
		return wrapError(errors.New("unknown or missing request type"))
	}
	return dispatchQuery(q)
}

func (s *Service) chaincodeQuery(q *discovery.Query) *discovery.QueryResult {
	if err := validateCCQuery(q.GetCcQuery()); err != nil {
		return wrapError(err)
	}
	var descriptors []*discovery.EndorsementDescriptor
	for _, interest := range q.GetCcQuery().Interests {
		desc, err := s.PeersForEndorsement(common2.ChannelID(q.Channel), interest)
		if err != nil {
			logger.Errorf("Failed constructing descriptor for chaincode %s: %v", interest, err)
			return wrapError(errors.Errorf("failed constructing descriptor for %v", interest))
		}
		descriptors = append(descriptors, desc)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check that the client SDK fully populates the discovery.Query content (e.g. SetCcQuery/SetPeerMembershipQuery) before sending
  2. Align client SDK and Fabric peer versions so query types are mutually supported
  3. Send local-only queries (e.g. local peers) to the local discovery port/endpoint configuration and channel queries with a channel set
  4. Inspect the serialized request if hand-building gRPC calls and confirm the oneof Query_Content is set

Example fix

// before
q := &discovery.Query{} // empty content
// after
q := &discovery.Query{Content: &discovery.Query_CcQuery{CcQuery: &discovery.ChaincodeQuery{Interests: interests}}}
Defensive patterns

Strategy: type-guard

Validate before calling

if q.GetContent() == nil { return errors.New("discovery.Query has no content set") }

Type guard

func hasQueryContent(q *discovery.Query) bool {
  return q != nil && q.GetContent() != nil
}

Try / catch

result, err := client.Send(ctx, query)
if err != nil && strings.Contains(err.Error(), "unknown or missing request type") {
  // rebuild the Query with a populated oneof content and matching SDK/peer versions
}

Prevention

When it happens

Trigger: A discovery.Query protobuf with no Query_Content set (empty query), a QueryType unknown to protoext.GetQueryType, or a channel-scoped request that only exists as a local dispatcher (or vice versa) so the map lookup dispatchers[GetQueryType(q)] misses.

Common situations: Client SDK bug constructing an empty discovery.Query; version mismatch where newer query types are sent to an older peer; manually crafted gRPC requests to the discovery service; wrong endpoint used for local-only queries.

Related errors


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