{"record":{"id":"038e7b27c8dade55","repo":"alibaba/nacos","slug":"api-function-disabled-038e7b","errorCode":"API_FUNCTION_DISABLED","errorMessage":"Current functionMode is `naming`, config module is disabled.","messagePattern":"Current functionMode is `naming`, config module is disabled\\.","errorType":"exception","errorClass":"NacosApiException","httpStatus":501,"severity":"error","filePath":"console/src/main/java/com/alibaba/nacos/console/handler/impl/noop/config/ConfigNoopHandler.java","lineNumber":58,"sourceCode":"\n/**\n * Noop Implementation of ConfigHandler for handling internal configuration operations.\n * Used when `config` module is disabled(functionMode is `naming`)\n *\n * @author xiweng.yy\n */\n@Service\n@ConditionalOnMissingBean(value = ConfigHandler.class, ignored = ConfigNoopHandler.class)\npublic class ConfigNoopHandler implements ConfigHandler {\n    \n    private static final String MCP_NOT_ENABLED_MESSAGE =\n        \"Current functionMode is `naming`, config module is disabled.\";\n    \n    @Override\n    public Page<ConfigBasicInfo> getConfigList(int pageNo, int pageSize, String dataId,\n        String group,\n        String namespaceId, Map<String, Object> configAdvanceInfo) throws NacosException {\n        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,\n            ErrorCode.API_FUNCTION_DISABLED,\n            MCP_NOT_ENABLED_MESSAGE);\n    }\n    \n    @Override\n    public ConfigDetailInfo getConfigDetail(String dataId, String group, String namespaceId)\n        throws NacosException {\n        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,\n            ErrorCode.API_FUNCTION_DISABLED,\n            MCP_NOT_ENABLED_MESSAGE);\n    }\n    \n    @Override\n    public Boolean publishConfig(ConfigForm configForm, ConfigRequestInfo configRequestInfo)\n        throws NacosException {\n        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,\n            ErrorCode.API_FUNCTION_DISABLED,\n            MCP_NOT_ENABLED_MESSAGE);","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/console/src/main/java/com/alibaba/nacos/console/handler/impl/noop/config/ConfigNoopHandler.java#L40-L76","documentation":"Thrown by ConfigNoopHandler.getConfigList, the fallback ConfigHandler bean activated by @ConditionalOnMissingBean when the server runs with -Dnacos.functionMode=naming. Because ConditionFunctionEnabled.ConditionConfigEnabled does not match the 'naming' mode, the real config handler is never registered, so Spring injects ConfigNoopHandler and list-config calls return API_FUNCTION_DISABLED (40001) / HTTP 501.","triggerScenarios":"GET /v3/console/cs/config/list or /v3/admin/cs/config/list (or any client SDK config-list call routed through the console handler) against a server started with -Dnacos.functionMode=naming.","commonSituations":"A naming-only Nacos cluster is deployed for pure service discovery, but a tooling/UI still polls the config list. Mismatched functionMode between the node an operator set and the workload expectations after a 2.x->3.x migration.","solutions":["Do not call config APIs against a naming-only node — target a node whose functionMode enables config (unset, =config, =microservice, or =ai).","Restart the node without -Dnacos.functionMode=naming if config support is actually required for this deployment.","Verify the live mode with GET /v3/admin/core/state (function_mode key) before issuing config-list requests.","Remove the config-list call from clients pointed at the naming-only cluster."],"exampleFix":"# before\n-Dnacos.functionMode=naming   # ConfigNoopHandler active -> getConfigList -> 501\n\n# after — enable config on this node\n-Dnacos.functionMode=config   # or unset for all-modules","handlingStrategy":"validation","validationCode":"// GET {nacos}/v3/admin/core/state -> data[\"function_mode\"]\nString mode = serverState.get(\"function_mode\");\nboolean configEnabled = (mode == null || mode.isEmpty())\n    || \"config\".equalsIgnoreCase(mode)\n    || \"microservice\".equalsIgnoreCase(mode)\n    || \"ai\".equalsIgnoreCase(mode);\nif (!configEnabled) { /* do not call getConfigList; report config disabled */ }","typeGuard":null,"tryCatchPattern":"try {\n    handler.getConfigList(pageNo, pageSize, dataId, group, namespaceId, advanceInfo);\n} catch (NacosApiException e) {\n    if (e.getDetailErrCode() == ErrorCode.API_FUNCTION_DISABLED.getCode()) {\n        // config module disabled by functionMode=naming -> skip config UI\n    } else { throw e; }\n}","preventionTips":["Keep a known function_mode per cluster node in client config and never send config requests to naming-only nodes.","Cache the result of /v3/admin/core/state at startup and refresh on connection reset.","Gate config-list calls behind a configEnabled check so the UI never issues a 501-guaranteed request."],"tags":["function-mode","config","noop-handler","naming-only","configuration"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}