hyperledger/fabric · error

Chaincode %s with given certificate hash %v belongs to a dif

Error message

Chaincode %s with given certificate hash %v belongs to a different chaincode

What it means

After resolving the certificate hash to a registered name, the Authenticator verifies that the chaincode name carried in the REGISTER message matches the name registered for that certificate. A mismatch (someone presenting a valid cert but claiming a different chaincode name) is rejected with this error to prevent identity spoofing between chaincode connections.

Source

Thrown at core/chaincode/accesscontrol/access.go:90

	ccName := chaincodeID.Name
	// Obtain certificate from stream
	hash := extractCertificateHashFromContext(stream.Context())
	if len(hash) == 0 {
		errMsg := fmt.Sprintf("TLS is active but chaincode %s didn't send certificate", ccName)
		logger.Warning(errMsg)
		return errors.New(errMsg)
	}
	// Look it up in the mapper
	registeredName := ac.mapper.lookup(certHash(hash))
	if registeredName == "" {
		errMsg := fmt.Sprintf("Chaincode %s with given certificate hash %v not found in registry", ccName, hash)
		logger.Warning(errMsg)
		return errors.New(errMsg)
	}
	if registeredName != ccName {
		errMsg := fmt.Sprintf("Chaincode %s with given certificate hash %v belongs to a different chaincode", ccName, hash)
		logger.Warning(errMsg)
		return errors.New(errMsg)
	}

	logger.Debug("Chaincode", ccName, "'s authentication is authorized")
	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure CORE_CHAINCODE_ID_NAME in the chaincode container matches the name under which its TLS cert was registered/launched.
  2. Give each chaincode its own TLS certificate; do not share cert/key files across chaincode containers.
  3. Check launch scripts/K8s specs for copy-paste errors where cert files or chaincode names were swapped.
  4. Restart both peer and chaincode after fixing the name/cert pairing so mappings are rebuilt cleanly.

Example fix

// before: name mismatch on registration
CORE_CHAINCODE_ID_NAME=wrongcc:1.0 (with cert minted for mycc)
// after
CORE_CHAINCODE_ID_NAME=mycc:1.0 (with the cert minted for mycc)
Defensive patterns

Strategy: validation

Validate before calling

// ensure declared name matches the cert provisioned for it
if chaincodeName != expectedNameForCert(certPath) {
    return errors.New("chaincode name does not match provisioned TLS certificate")
}

Type guard

func nameMatchesCert(name, certPath string, known map[string]certHash) bool {
    cert, err := readCertDER(certPath)
    if err != nil { return false }
    h := sha256.Sum256(cert)
    return known[name] == certHash(h[:])
}

Try / catch

if err := authenticator.authenticate(msg, stream); err != nil {
    if strings.Contains(err.Error(), "belongs to a different chaincode") {
        // fix CORE_CHAINCODE_ID_NAME / cert pairing and reconnect
    }
}

Prevention

When it happens

Trigger: ChaincodeMessage_REGISTER whose ChaincodeID.Name differs from the registeredName that the mapper resolved for the presented TLS certificate hash — e.g., a connection for chaincode A sending a REGISTER claiming name B.

Common situations: Two chaincodes swapped TLS certificates or shared a cert file; a client SDK or test harness connecting with the wrong CORE_CHAINCODE_ID_NAME; container reuse where a cert minted for one chaincode is mounted into another.

Understand the failure class

Related errors


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