hyperledger/fabric · error

Received bad response, status %d: %s

Error message

Received bad response, status %d: %s

What it means

Returned by getChannels when the endorser replied but with a non-200 response status or a nil Response. The proposal reached the peer and was evaluated, yet the peer rejected the GetChannels query; its status code and message are interpolated into the error.

Source

Thrown at internal/peer/channel/list.go:73

	c, _ := cc.cf.Signer.Serialize()
	prop, _, err = protoutil.CreateProposalFromCIS(common2.HeaderType_ENDORSER_TRANSACTION, "", invocation, c)
	if err != nil {
		return nil, fmt.Errorf("Cannot create proposal, due to %s", err)
	}

	var signedProp *pb.SignedProposal
	signedProp, err = protoutil.GetSignedProposal(prop, cc.cf.Signer)
	if err != nil {
		return nil, fmt.Errorf("Cannot create signed proposal, due to %s", err)
	}

	proposalResp, err := cc.cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
	if err != nil {
		return nil, fmt.Errorf("Failed sending proposal, got %s", err)
	}

	if proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {
		return nil, fmt.Errorf("Received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
	}

	var channelQueryResponse pb.ChannelQueryResponse
	err = proto.Unmarshal(proposalResp.Response.Payload, &channelQueryResponse)
	if err != nil {
		return nil, fmt.Errorf("Cannot read channels list response, %s", err)
	}

	return channelQueryResponse.Channels, nil
}

func list(cf *ChannelCmdFactory) error {
	var err error
	if cf == nil {
		cf, err = InitCmdFactory(EndorserRequired, PeerDeliverNotRequired, OrdererNotRequired)
		if err != nil {
			return err
		}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the embedded status and message for the peer-side reason
  2. Ensure the client identity belongs to the organization/peer network (MSP membership)
  3. Check peer logs around the request for the qscc failure
  4. Verify peer binary and CLI are from compatible Fabric versions

Example fix

// before: non-member identity -> 403-style response
if proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {
    return nil, fmt.Errorf("Received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
}
// after: also log payload for diagnostics
if proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {
    log.Printf("endorser response status=%d payload=%q", proposalResp.Response.Status, string(proposalResp.Response.GetPayload()))
    return nil, fmt.Errorf("Received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
}
Defensive patterns

Strategy: type-guard

Validate before calling

// pre-flight: ensure identity is a network member (e.g. org enrolled and channel-joined)
out, err := exec.Command("peer", "channel", "list").CombinedOutput()
_ = out; _ = err // membership errors surface as non-200 endorser responses

Type guard

func isOK(resp *pb.ProposalResponse) bool {
    return resp != nil && resp.Response != nil && resp.Response.Status == http.StatusOK
}

Try / catch

if proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {
    // 403/404-ish: identity/permission or channel unknown; 500: qscc failure -> check peer logs
    return nil, fmt.Errorf("Received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
}

Prevention

When it happens

Trigger: proposalResp.Response == nil or proposalResp.Response.Status != http.StatusOK — the qscc GetChannels chaincode invocation failed on the peer (e.g. access denied for the caller's identity, system chaincode error, unknown/unavailable ledger).

Common situations: Caller's identity is not a member of any channel or lacks rights to invoke qscc; peer still initializing its ledger; peer and CLI version skew; response payload not produced because chaincode returned an error status.

Related errors


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