hyperledger/fabric · error
duplicate chaincodeID: %s
Error message
duplicate chaincodeID: %s
What it means
Returned by HandlerRegistry.Register when a chaincode handler tries to register a chaincodeID that already has a live registered handler. Each running chaincode instance must register exactly once per chaincodeID; a second registration means two containers claim the same chaincode.
Source
Thrown at core/chaincode/handler_registry.go:135
// Handler retrieves the handler for a chaincode instance.
func (r *HandlerRegistry) Handler(ccid string) *Handler {
r.mutex.Lock()
h := r.handlers[ccid]
r.mutex.Unlock()
return h
}
// Register adds a chaincode handler to the registry.
// An error will be returned if a handler is already registered for the
// chaincode. An error will also be returned if the chaincode has not already
// been "launched", and unsolicited registration is not allowed.
func (r *HandlerRegistry) Register(h *Handler) error {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.handlers[h.chaincodeID] != nil {
chaincodeLogger.Debugf("duplicate registered handler(key:%s) return error", h.chaincodeID)
return errors.Errorf("duplicate chaincodeID: %s", h.chaincodeID)
}
// This chaincode was not launched by the peer but is attempting
// to register. Only allowed in development mode.
if r.launching[h.chaincodeID] == nil && !r.allowUnsolicitedRegistration {
return errors.Errorf("peer will not accept external chaincode connection %s (except in dev mode)", h.chaincodeID)
}
r.handlers[h.chaincodeID] = h
chaincodeLogger.Debugf("registered handler complete for chaincode %s", h.chaincodeID)
return nil
}
// Deregister clears references to state associated specified chaincode.
// As part of the cleanup, it closes the handler so it can cleanup any state.
// If the registry does not contain the provided handler, an error is returned.
func (r *HandlerRegistry) Deregister(ccid string) error {View on GitHub (pinned to 2736b63f8f)
Solutions
- Stop and remove the stale chaincode container (docker rm -f <chaincode-container>) and retry.
- Restart the peer to clear the stale handler registry entry if containers are already gone.
- In dev mode, ensure only one chaincode process connects with a given chaincodeID.
- Check for orphaned containers from previous launches and clean them up (docker ps -a).
Example fix
// before: start chaincode while old one still running CORE_CHAINCODE_ID_NAME=mycc:1.0 peer chaincode launch ... // after docker rm -f $(docker ps -aq --filter name=dev-peer-mycc) CORE_CHAINCODE_ID_NAME=mycc:1.0 peer chaincode launch ...
Defensive patterns
Strategy: validation
Validate before calling
// before starting a chaincode container, ensure no instance is running docker ps --filter name=dev-peer --filter status=running # stop stale containers first: docker rm -f $(docker ps -aq --filter name=dev-peer-mycc)
Prevention
- Always clean up old chaincode containers before relaunching.
- Never start two chaincode processes with the same CORE_CHAINCODE_ID_NAME.
- After peer restarts, verify with `peer chaincode list` and prune orphan containers.
When it happens
Trigger: A second chaincode container/process connects to the peer and calls Register with a chaincodeID whose entry in r.handlers is non-nil (the first handler is still connected).
Common situations: Old chaincode container still alive while a new one starts (stale docker container); restarting chaincode without the peer releasing the old handler; launching the same chaincode twice manually (e.g. dev mode double-start); orphaned containers after peer restart.
Related errors
- error in handling register chaincode, chaincodeID name is em
- peer will not accept external chaincode connection %s (excep
- First message needs to be a register
- TLS is active but chaincode %s didn't send certificate
- Chaincode %s with given certificate hash %v not found in reg
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b3220a2c4f69038c.
Report an issue: GitHub.