hyperledger/fabric · error

ConfigUpdate for channel '%s' but envelope for channel '%s'

Error message

ConfigUpdate for channel '%s' but envelope for channel '%s'

What it means

The channel ID inside the ConfigUpdate does not match the channel this validator was created for. An update envelope is only valid for its intended channel; a mismatch means the envelope was built for, or is being validated against, the wrong channel.

Source

Thrown at common/configtx/update.go:127

		}
	}
	return nil
}

// authorizeUpdate validates that all modified config has the corresponding modification policies satisfied by the signature set
// it returns a map of the modified config
func (vi *ValidatorImpl) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelope) (map[string]comparable, error) {
	if configUpdateEnv == nil {
		return nil, errors.Errorf("cannot process nil ConfigUpdateEnvelope")
	}

	configUpdate, err := UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
	if err != nil {
		return nil, err
	}

	if configUpdate.ChannelId != vi.channelID {
		return nil, errors.Errorf("ConfigUpdate for channel '%s' but envelope for channel '%s'", configUpdate.ChannelId, vi.channelID)
	}

	readSet, err := mapConfig(configUpdate.ReadSet, vi.namespace)
	if err != nil {
		return nil, errors.Wrapf(err, "error mapping ReadSet")
	}
	err = vi.verifyReadSet(readSet)
	if err != nil {
		return nil, errors.Wrapf(err, "error validating ReadSet")
	}

	writeSet, err := mapConfig(configUpdate.WriteSet, vi.namespace)
	if err != nil {
		return nil, errors.Wrapf(err, "error mapping WriteSet")
	}

	deltaSet := computeDeltaSet(readSet, writeSet)
	signedData, err := protoutil.ConfigUpdateEnvelopeAsSignedData(configUpdateEnv)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Regenerate the update with the correct channel_id matching the target channel (configtxlator / configtxgen -channelID).
  2. Verify you are submitting the update transaction to the intended channel (peer channel update -c <channel>).
  3. Re-fetch the current config from the correct channel and rebuild the diff.

Example fix

// before
{"channel_id": "channel-a", ...}
// after
{"channel_id": "mychannel", ...}
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the update's channel matches the target before submitting
func checkChannel(update *cb.ConfigUpdate, channelID string) error {
    if update.GetChannelId() != channelID {
        return fmt.Errorf("update targets %q, expected %q", update.GetChannelId(), channelID)
    }
    return nil
}

Try / catch

if _, err := validator.ProposeConfigUpdate(env, seq); err != nil {
    if strings.Contains(err.Error(), "but envelope for channel") {
        // rebuild update for the correct channel before retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling proposeConfigUpdate/Validate with a ConfigUpdateEnvelope whose ConfigUpdate.channel_id differs from vi.channelID — e.g. submitting an update generated for channel A to the validator of channel B.

Common situations: Mixing up update files when operating multiple channels; copying an example update and forgetting to change channel_id; using a fetched config from one channel to build an update submitted to another.

Related errors


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