{"record":{"id":"e7abb4da43e44e38","repo":"hyperledger/fabric","slug":"could-not-find-handler-s","errorCode":null,"errorMessage":"could not find handler: %s","messagePattern":"could not find handler: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/chaincode/handler_registry.go","lineNumber":163,"sourceCode":"\n\tchaincodeLogger.Debugf(\"registered handler complete for chaincode %s\", h.chaincodeID)\n\treturn nil\n}\n\n// Deregister clears references to state associated specified chaincode.\n// As part of the cleanup, it closes the handler so it can cleanup any state.\n// If the registry does not contain the provided handler, an error is returned.\nfunc (r *HandlerRegistry) Deregister(ccid string) error {\n\tchaincodeLogger.Debugf(\"deregister handler: %s\", ccid)\n\n\tr.mutex.Lock()\n\thandler := r.handlers[ccid]\n\tdelete(r.handlers, ccid)\n\tdelete(r.launching, ccid)\n\tr.mutex.Unlock()\n\n\tif handler == nil {\n\t\treturn errors.Errorf(\"could not find handler: %s\", ccid)\n\t}\n\n\thandler.Close()\n\n\tchaincodeLogger.Debugf(\"deregistered handler with key: %s\", ccid)\n\treturn nil\n}\n\ntype TxQueryExecutorGetter struct {\n\tHandlerRegistry *HandlerRegistry\n\tCCID            string\n}\n\nfunc (g *TxQueryExecutorGetter) TxQueryExecutor(chainID, txID string) ledger.SimpleQueryExecutor {\n\thandler := g.HandlerRegistry.Handler(g.CCID)\n\tif handler == nil {\n\t\treturn nil\n\t}","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler_registry.go#L145-L181","documentation":"Returned by HandlerRegistry.Deregister when no handler exists for the given chaincodeID in the registry. The peer looked up r.handlers[ccid], found nil, and refuses to close/deregister a handler that was never (or no longer) registered.","triggerScenarios":"Deregister(ccid) is called for a chaincodeID not present in r.handlers — e.g. double deregistration, deregistering a chaincode that never registered, or after the registry entry was already deleted.","commonSituations":"Chaincode connection closes twice (handler cleanup race); peer restarting while a chaincode exits and calls deregister; a launch failure path deregistering a handler that failed registration; tests calling Deregister with a fabricated chaincodeID.","solutions":["Verify the chaincodeID passed to Deregister matches one that is currently registered.","Treat the error as benign in cleanup paths — log and continue if the handler is already gone.","Check for double-close/double-deregister logic in the shutdown path and guard it.","Capture peer logs around chaincode exit to find why the handler was missing (crash before full registration)."],"exampleFix":"// cleanup path\n// before\nif err := registry.Deregister(ccid); err != nil { return err }\n// after\nif err := registry.Deregister(ccid); err != nil {\n    logger.Debugf(\"deregister skipped: %v\", err) // handler already gone\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := registry.Deregister(ccid); err != nil && strings.Contains(err.Error(), \"could not find handler\") {\n    // benign: handler already gone; log at debug and continue cleanup\n}","preventionTips":["Idempotent cleanup: treat missing-handler deregistration as success.","Guard shutdown paths against double-deregistration.","Correlate chaincode exit logs with peer deregistration logs to spot race conditions."],"tags":["hyperledger-fabric","chaincode","deregistration","lifecycle"],"backgroundTag":"handler-not-found","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}