apache/incubator-seata · warning · NotSupportYetException

not support atomic operation putConfigIfAbsent

Error message

not support atomic operation putConfigIfAbsent

What it means

NacosConfiguration.putConfigIfAbsent unconditionally throws NotSupportYetException because Nacos's publishConfig API has no atomic create-if-absent semantics — a publish always overwrites. Seata surfaces this rather than silently faking atomicity when a caller requests the put-if-absent contract (used e.g. by config-center migration/CLUSTER operations).

Source

Thrown at config/seata-config-nacos/src/main/java/org/apache/seata/config/nacos/NacosConfiguration.java:137

    @Override
    public boolean putConfig(String dataId, String content, long timeoutMills) {
        boolean result = false;
        try {
            if (!seataConfig.isEmpty()) {
                seataConfig.setProperty(dataId, content);
                result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr());
            } else {
                result = configService.publishConfig(dataId, getNacosGroup(), content);
            }
        } catch (NacosException exx) {
            LOGGER.error(exx.getErrMsg());
        }
        return result;
    }

    @Override
    public boolean putConfigIfAbsent(String dataId, String content, long timeoutMills) {
        throw new NotSupportYetException("not support atomic operation putConfigIfAbsent");
    }

    @Override
    public boolean removeConfig(String dataId, long timeoutMills) {
        boolean result = false;
        try {
            if (!seataConfig.isEmpty()) {
                seataConfig.remove(dataId);
                result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr());
            } else {
                result = configService.removeConfig(dataId, getNacosGroup());
            }
        } catch (NacosException exx) {
            LOGGER.error(exx.getErrMsg());
        }
        return result;
    }

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Check support before calling: NacosConfiguration does not implement putConfigIfAbsent — use putConfig and handle idempotency yourself
  2. Pre-check existence with getConfig(dataId, timeoutMills) and only publish when absent (accepting the non-atomic race window)
  3. Catch NotSupportYetException and fall back to putConfig for backends without atomic create
  4. If atomicity is mandatory, use a backend that supports it (e.g. Zookeeper/etcd-style CAS) instead of Nacos

Example fix

// before
boolean created = configuration.putConfigIfAbsent(dataId, content, timeout);

// after
if (configuration.getConfig(dataId, timeout) == null) {
    configuration.putConfig(dataId, content, timeout);
}
Defensive patterns

Strategy: fallback

Validate before calling

if (configuration instanceof NacosConfiguration) { /* avoid putConfigIfAbsent; check-then-put */ }

Type guard

boolean supportsPutIfAbsent(Configuration c) { try { return !(c instanceof NacosConfiguration); } catch (Exception e) { return false; } }

Try / catch

try { configuration.putConfigIfAbsent(id, content, timeout); } catch (NotSupportYetException e) { if (configuration.getConfig(id, timeout) == null) configuration.putConfig(id, content, timeout); }

Prevention

When it happens

Trigger: Calling Configuration.putConfigIfAbsent(dataId, content, timeoutMills) (directly or via Seata ops tooling that imports/migrates config into Nacos as the target config store).

Common situations: Running a config import/migration tool or console operation that assumes all backends support atomic put-if-absent, against a Nacos-backed seata-server configuration.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/9bfa679b4c227518. Report an issue: GitHub.