hyperledger/fabric · error

group %s isn't mapped to endorsers, but exists in a layout

Error message

group %s isn't mapped to endorsers, but exists in a layout

What it means

createEndorsementDescriptor validates that every group referenced in an endorsement descriptor's Layouts (QuantitiesByGroup) also appears in the descriptor's EndorsersByGroups map. When a layout requires a group the server never populated with endorsers, this error names the missing group. It indicates inconsistent endorsement descriptor data returned by the discovery server.

Source

Thrown at discovery/client/client.go:510

			return err
		}
		resp[key] = descriptor
	}

	return nil
}

func (resp response) createEndorsementDescriptor(desc *discovery.EndorsementDescriptor, channel string) (*endorsementDescriptor, error) {
	descriptor := &endorsementDescriptor{
		layouts:           []map[string]int{},
		endorsersByGroups: make(map[string][]*Peer),
	}
	for _, l := range desc.Layouts {
		currentLayout := make(map[string]int)
		descriptor.layouts = append(descriptor.layouts, currentLayout)
		for grp, count := range l.QuantitiesByGroup {
			if _, exists := desc.EndorsersByGroups[grp]; !exists {
				return nil, errors.Errorf("group %s isn't mapped to endorsers, but exists in a layout", grp)
			}
			currentLayout[grp] = int(count)
		}
	}

	for grp, peers := range desc.EndorsersByGroups {
		var endorsers []*Peer
		for _, p := range peers.Peers {
			peer, err := endorser(p, desc.Chaincode, channel)
			if err != nil {
				return nil, errors.Wrap(err, "failed creating endorser object")
			}
			endorsers = append(endorsers, peer)
		}
		descriptor.endorsersByGroups[grp] = endorsers
	}

	return descriptor, nil

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure all organizations/groups in the endorsement policy have reachable peers that joined the channel
  2. Verify anchor peers are configured so gossip disseminates membership across orgs
  3. Check that the endorsement policy's required orgs actually have peers running the chaincode
  4. Retry after gossip converges (peers may still be joining)
  5. Inspect peer discovery logs to see why the group's endorsers list is empty
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check: all orgs in the endorsement policy have live peers
for _, org := range policyOrgs(channel) {
	if !hasLivePeerInOrg(channel, org) {
		return fmt.Errorf("org %s has no live peers on channel %s", org, channel)
	}
}

Try / catch

desc, err := resolveEndorsers(ctx)
if err != nil && strings.Contains(err.Error(), "isn't mapped to endorsers") {
	// org peers likely still joining; wait and retry
	time.Sleep(5 * time.Second)
	desc, err = resolveEndorsers(ctx)
}

Prevention

When it happens

Trigger: Processing a discovery ChaincodeQueryResult whose EndorsementDescriptor has a layout quantity key with no matching entry in EndorsersByGroups — typically when the server has layout plans for peers/groups (e.g. by MSP or organization) but no live endorsers discovered for that group.

Common situations: An organization's peers are down or not gossiped yet so the server knows the layout but has no endorsers for the group; anchor peer misconfiguration breaking cross-org gossip; new org added to channel policy before its peers joined; stale discovery cache on the peer.

Related errors


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