alibaba/nacos · error · NacosApiException

API_FUNCTION_DISABLED

API_FUNCTION_DISABLED

Error message

Current functionMode is `naming`, config module is disabled.

What it means

Thrown by HistoryNoopHandler.getConfigHistoryInfo under functionMode=naming. Reading a single config-history detail (by nid) needs config-module history persistence, which is not loaded in naming-only mode, so the noop handler returns API_FUNCTION_DISABLED (40001) / HTTP 501.

Source

Thrown at console/src/main/java/com/alibaba/nacos/console/handler/impl/noop/config/HistoryNoopHandler.java:49

/**
 * Noop Implementation of HistoryHandler for handling internal configuration operations.
 * Used when `config` module is disabled(functionMode is `naming`)
 *
 * @author xiweng.yy
 */
@Service
@ConditionalOnMissingBean(value = HistoryHandler.class, ignored = HistoryNoopHandler.class)
public class HistoryNoopHandler implements HistoryHandler {
    
    private static final String MCP_NOT_ENABLED_MESSAGE =
        "Current functionMode is `naming`, config module is disabled.";
    
    @Override
    public ConfigHistoryDetailInfo getConfigHistoryInfo(String dataId, String group,
        String namespaceId, Long nid)
        throws NacosException {
        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,
            ErrorCode.API_FUNCTION_DISABLED,
            MCP_NOT_ENABLED_MESSAGE);
    }
    
    @Override
    public Page<ConfigHistoryBasicInfo> listConfigHistory(String dataId, String group,
        String namespaceId,
        Integer pageNo, Integer pageSize) throws NacosException {
        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,
            ErrorCode.API_FUNCTION_DISABLED,
            MCP_NOT_ENABLED_MESSAGE);
    }
    
    @Override
    public ConfigHistoryDetailInfo getPreviousConfigHistoryInfo(String dataId, String group,
        String namespaceId,
        Long id) throws NacosException {
        throw new NacosApiException(NacosException.SERVER_NOT_IMPLEMENTED,

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Query config history against a config-enabled node (functionMode unset, =config, =microservice, or =ai).
  2. Restart the node in a config-capable mode if history reads are expected here.
  3. Verify function_mode via GET /v3/admin/core/state before calling.
  4. Re-point the audit tool to a config-capable node.

Example fix

# before
-Dnacos.functionMode=naming   # getConfigHistoryInfo -> 501

# after
# read history on a node with the config module enabled
Defensive patterns

Strategy: validation

Validate before calling

// Verify config module before getConfigHistoryInfo.
String mode = serverState.get("function_mode");
boolean configEnabled = (mode == null || mode.isEmpty())
    || "config".equalsIgnoreCase(mode)
    || "microservice".equalsIgnoreCase(mode)
    || "ai".equalsIgnoreCase(mode);
if (!configEnabled) { /* skip history detail query */ }

Try / catch

try {
    handler.getConfigHistoryInfo(dataId, group, namespaceId, nid);
} catch (NacosApiException e) {
    if (e.getDetailErrCode() == ErrorCode.API_FUNCTION_DISABLED.getCode()) {
        // config disabled -> history unavailable on this node
    } else { throw e; }
}

Prevention

When it happens

Trigger: GET /v3/console/cs/history or /v3/admin/cs/history?dataId=...&group=...&namespaceId=...&nid=... against a naming-only server.

Common situations: An audit/compliance tool reads config change history from a naming-only node; functionMode=naming slims the cluster but the history audit still runs here.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/fff60375328ace10. Report an issue: GitHub.