{"record":{"id":"e2a3e5f6c19f0669","repo":"hyperledger/fabric","slug":"channel-participation-api-is-disabled","errorCode":null,"errorMessage":"channel participation API is disabled","messagePattern":"channel participation API is disabled","errorType":"http","errorClass":null,"httpStatus":503,"severity":"error","filePath":"orderer/common/channelparticipation/restapi.go","lineNumber":260,"sourceCode":"\t//    '400':\n\t//      description: Bad request.\n\t//    '404':\n\t//      description: The channel or block does not exist.\n\n\thandler.router.HandleFunc(urlWithChannelAndBlockIDKey, handler.serveFetchBlock).Methods(http.MethodGet)\n\n\thandler.router.HandleFunc(urlWithChannelAndBlockIDKey, handler.serveNotAllowed)\n\thandler.router.HandleFunc(urlWithChannelIDKey, handler.serveNotAllowed)\n\thandler.router.HandleFunc(URLBaseV1Channels, handler.serveNotAllowed)\n\n\thandler.router.HandleFunc(URLBaseV1, handler.redirectBaseV1).Methods(http.MethodGet)\n\n\treturn handler\n}\n\nfunc (h *HTTPHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {\n\tif !h.config.Enabled {\n\t\terr := errors.New(\"channel participation API is disabled\")\n\t\th.sendResponseJsonError(resp, http.StatusServiceUnavailable, err)\n\t\treturn\n\t}\n\n\th.router.ServeHTTP(resp, req)\n}\n\n// List all channels\nfunc (h *HTTPHandler) serveListAll(resp http.ResponseWriter, req *http.Request) {\n\t_, err := negotiateContentType(req) // Only application/json responses for now\n\tif err != nil {\n\t\th.sendResponseJsonError(resp, http.StatusNotAcceptable, err)\n\t\treturn\n\t}\n\tchannelList := h.registrar.ChannelList()\n\tif channelList.SystemChannel != nil && channelList.SystemChannel.Name != \"\" {\n\t\tchannelList.SystemChannel.URL = path.Join(URLBaseV1Channels, channelList.SystemChannel.Name)\n\t}","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/channelparticipation/restapi.go#L242-L278","documentation":"The channel participation API HTTP handler is guarded by a configuration flag; when channel participation (the REST join/remove/list endpoints) is disabled in the orderer config, ServeHTTP rejects every request with 503 and this error. The route still exists but is intentionally inert.","triggerScenarios":"Sending any request to the orderer's /participation endpoints (join, remove, list) while GENERAL.CHANNELPARTICIPATION.ENABLED is false in orderer.yaml.","commonSituations":"Admin forgot to enable the participation API before running osnadmin; connecting an automation tool (osnadmin channel join) to an orderer whose config predates or omits the feature; Docker image/env not passing CHANNELPARTICIPATION.ENABLED=true.","solutions":["Set channelParticipation.enabled: true in orderer.yaml (or env OVERORDERER... CHANNELPARTICIPATION_ENABLED equivalent) and restart the orderer","Use osnadmin with the orderer's admin endpoint/port that actually serves the participation API","If the orderer manages channels via the legacy system-chain/Jaeger path, use the appropriate channel-creation flow instead of the participation API"],"exampleFix":"// before (orderer.yaml)\nChannelParticipation:\n  Enabled: false\n// after\nChannelParticipation:\n  Enabled: true\n  MaxRequestBodySize: 1024 * 1024","handlingStrategy":"validation","validationCode":"// before calling the API, verify the orderer config flag\n// orderer.yaml: ChannelParticipation.Enabled must be true\ncfgEnabled := os.Getenv(\"ORDERER_CHANNELPARTICIPATION_ENABLED\") == \"true\"\nif !cfgEnabled { return errors.New(\"participation API disabled on this orderer\") }","typeGuard":null,"tryCatchPattern":"resp, err := http.Post(url, \"\", body)\nif resp != nil && resp.StatusCode == http.StatusServiceUnavailable {\n\treturn errors.New(\"channel participation API is disabled; enable ChannelParticipation.Enabled and restart orderer\")\n}","preventionTips":["Enable channelParticipation.enabled in orderer.yaml for osnadmin-based channel management","Automate a preflight config check on orderer startup scripts","Point osnadmin at the admin listener that serves the participation API","Verify with GET /participation/v1/channels before attempting joins"],"tags":["orderer","configuration","http","api"],"backgroundTag":"api-disabled-by-config","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"}