hyperledger/fabric · error
received bad response, status %d: %s
Error message
received bad response, status %d: %s
What it means
Returned by joinBySnapshotStatus when the endorser responded but with a non-200 status (or a nil Response). The proposal was processed by the peer, but the chaincode-level execution rejected it; the peer's status code and message are included in the error.
Source
Thrown at internal/peer/channel/joinbysnapshotstatus.go:93
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, due to %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)
}
joinbysnapshotStatus := &pb.JoinBySnapshotStatus{}
err = proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus)
if err != nil {
return nil, fmt.Errorf("cannot query joinbysnapshot status, due to %s", err)
}
return joinbysnapshotStatus, nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Read the status code and message embedded in the error for the peer-side reason
- Verify the channel exists on the peer and a snapshot/join-by-snapshot operation is actually in progress
- Ensure peer and CLI versions both support the joinbysnapshot feature (v3.x)
- Check peer logs at the time of the request for the underlying chaincode error
Example fix
// before: querying status when no join-by-snapshot in progress -> peer returns 500
peer channel joinbysnapshot status -c mychannel
// after: verify state first / handle non-200 explicitly
if resp.Response != nil && resp.Response.Status != http.StatusOK {
log.Printf("peer rejected status query (%d): %s", resp.Response.Status, resp.Response.Message)
} Defensive patterns
Strategy: type-guard
Type guard
func okEndorserResponse(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 {
// branch on status: 500 -> peer/chaincode issue; 403 -> permissions; retry only transient codes
return nil, fmt.Errorf("received bad response, status %d: %s", proposalResp.Response.Status, proposalResp.Response.Message)
} Prevention
- Confirm the join-by-snapshot operation is actually in progress before querying status
- Match peer and CLI versions (joinbysnapshot requires Fabric 3.x)
- Read the embedded status message before changing configuration
- Monitor peer logs when automating these queries
When it happens
Trigger: proposalResp.Response == nil or proposalResp.Response.Status != http.StatusOK — e.g. the peer returns 500 because the JoinBySnapshotStatus chaincode call failed internally, or 403/404 style errors from endorsement policy/unknown channel.
Common situations: The peer does not have the channel/snapshot context the command expects; chaincode handler on the peer errors out (snapshot metadata missing or join not in progress); client lacks permission to query; peer version doesn't support joinbysnapshot (feature not enabled).
Related errors
- Received bad response, status %d: %s
- only applicable for private data
- unknown operation type
- error reading chaincode install package at %s
- chaincode %s exists
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/04fabb19e24ead5b.
Report an issue: GitHub.