apache/incubator-seata · error · IllegalArgumentException
custom config type name %s is not allowed
Error message
custom config type name %s is not allowed
What it means
Thrown by CustomConfigurationProvider.provide() when the value of custom.name equals the name of a built-in ConfigType (e.g. nacos, apollo, zk, consul, etcd3, file, custom). Seata rejects it because the Custom type exists precisely to delegate to non-built-in providers; a built-in name here would either recurse (custom) or shadow native handling.
Source
Thrown at config/seata-config-custom/src/main/java/org/apache/seata/config/custom/CustomConfigurationProvider.java:42
import org.apache.seata.config.ConfigurationFactory;
import org.apache.seata.config.ConfigurationKeys;
import org.apache.seata.config.ConfigurationProvider;
import java.util.stream.Stream;
@LoadLevel(name = "Custom")
public class CustomConfigurationProvider implements ConfigurationProvider {
@Override
public Configuration provide() {
String pathDataId = ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
+ ConfigType.Custom.name().toLowerCase() + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
+ "name";
String name = ConfigurationFactory.CURRENT_FILE_INSTANCE.getConfig(pathDataId);
if (StringUtils.isBlank(name)) {
throw new IllegalArgumentException("name value of custom config type must not be blank");
}
if (Stream.of(ConfigType.values()).anyMatch(ct -> ct.name().equalsIgnoreCase(name))) {
throw new IllegalArgumentException(String.format("custom config type name %s is not allowed", name));
}
return EnhancedServiceLoader.load(ConfigurationProvider.class, name).provide();
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- If you want a built-in backend, drop the Custom indirection: set `config.type = nacos` (etc.) directly
- If you truly have a custom provider, give it a name that does not collide with any ConfigType enum constant, e.g. 'mycompany-config'
- If delegating to a built-in via your own wrapper, register the wrapper under a distinct @LoadLevel name
Example fix
# before
config:
type: custom
custom:
name: nacos
# after
config:
type: nacos
name: seata-server.properties Defensive patterns
Strategy: validation
Validate before calling
if (Stream.of(ConfigType.values()).anyMatch(ct -> ct.name().equalsIgnoreCase(name))) throw new IllegalStateException("custom.name must not be a built-in type name"); Try / catch
try { provider.provide(); } catch (IllegalArgumentException e) { log.error(e.getMessage()); /* fall back to direct built-in type */ } Prevention
- Prefix custom provider names with a namespace (e.g. acme-config)
- Do not copy built-in backend names into the custom.name slot
- Document the reserved built-in names for your team
When it happens
Trigger: `config.type = custom` combined with `custom.name = nacos` (or file, zk, apollo, consul, etcd3, redis, custom — matched case-insensitively). The stream check Stream.of(ConfigType.values()).anyMatch(ct -> ct.name().equalsIgnoreCase(name)) fires before the SPI load.
Common situations: Copy-pasting an existing config block and changing only `type: custom` while leaving the old backend name in place, or misunderstanding Custom as an alias indirection for built-in types.
Related errors
- name value of custom config type must not be blank
- ERR_CONFIG
- No JsonCodec provider found. Please add json-common-core to
- not found service provider for : {} caused by {}
- not found service provider for : {}
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/20fa8542afccfb8f.
Report an issue: GitHub.