hyperledger/fabric · error

nil request

Error message

nil request

What it means

validateStructure rejects the discovery request outright when the SignedRequest pointer is nil. The discovery service cannot even attempt to parse or authenticate a nil request, so it fails fast with this sentinel error before any signature or identity checks.

Source

Thrown at discovery/service.go:235

		for _, id := range peerIdentities {
			// Check peer exists in alive membership view
			aliveInfo, exists := peerAliveInfo[string(id.PKIId)]
			if !exists {
				continue
			}
			peersForCurrentOrg[string(id.PKIId)] = &discovery.Peer{
				Identity:       id.Identity,
				MembershipInfo: aliveInfo.Envelope,
			}
		}
	}
	return peersByOrg
}

// validateStructure validates that the request contains all the needed fields and that they are computed correctly
func validateStructure(ctx context.Context, request *discovery.SignedRequest, tlsEnabled bool, certHashFromContext certHashExtractor) (*discovery.Request, error) {
	if request == nil {
		return nil, errors.New("nil request")
	}
	req, err := protoext.SignedRequestToRequest(request)
	if err != nil {
		return nil, errors.Wrap(err, "failed parsing request")
	}
	if req.Authentication == nil {
		return nil, errors.New("access denied, no authentication info in request")
	}
	if len(req.Authentication.ClientIdentity) == 0 {
		return nil, errors.New("access denied, client identity wasn't supplied")
	}
	if !tlsEnabled {
		return req, nil
	}
	computedHash := certHashFromContext(ctx)
	if len(computedHash) == 0 {
		return nil, errors.New("client didn't send a TLS certificate")
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure a *discovery.SignedRequest is constructed (via discovery.NewRequest().... and signing) before calling Send
  2. Check your client code path for a branch that can pass a nil request to Send
  3. If using a helper/wrapper, validate the request parameter is non-nil before dispatching
  4. On the server this is a client bug — inspect client logs to find where the nil request originated

Example fix

// before
var req *discovery.SignedRequest
resp, err := client.Send(ctx, req) // nil request
// after
req := discovery.NewRequest().SetAuthentication(clientIdentity, tlsCertHash).SetPeersInterests(...).ToSignedRequest()
signedReq, err := req.Sign(key)
if err != nil { return err }
resp, err := client.Send(ctx, signedReq)
Defensive patterns

Strategy: validation

Validate before calling

if signedReq == nil {
    return errors.New("discovery: signed request is nil; build and sign a request first")
}

Type guard

func isNilRequest(r *discovery.SignedRequest) bool { return r == nil }

Try / catch

resp, err := client.Send(ctx, signedReq)
if err != nil {
    if strings.Contains(err.Error(), "nil request") {
        return nil, fmt.Errorf("programming error: request never built: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: The gRPC handler Discover receives a nil *discovery.SignedRequest. Client-side, this happens when a caller passes nil to the discovery client's Send method or constructs a request object that was never initialized.

Common situations: Calling client.Send(ctx, nil) or forgetting to build a request (e.g. NewSignedRequest/ComputeHashtoSign flow skipped); a wrapper function that drops the request on an error path; miswired test harness passing nil.

Related errors


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