apache/incubator-seata · critical · IllegalArgumentException
applicationId: %s, txServiceGroup: %s
Error message
applicationId: %s, txServiceGroup: %s
What it means
Thrown by GlobalTransactionScanner.afterPropertiesSet()/initClient() when either the application id or the transaction service group is null/empty at TM/RM client initialization time. The message echoes both values ('applicationId: %s, txServiceGroup: %s') so you can immediately see which one is missing. It is the standard Seata startup failure for an incompletely configured Seata client.
Source
Thrown at compatible/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java:145
boolean exposeProxy,
FailureHandler failureHandlerHook) {
super(applicationId, txServiceGroup, mode, exposeProxy, failureHandlerHook);
}
protected void initClient() {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Initializing Global Transaction Clients ... ");
}
if (DEFAULT_TX_GROUP_OLD.equals(getTxServiceGroup())) {
LOGGER.warn(
"the default value of seata.tx-service-group: {} has already changed to {} since Seata 1.5, "
+ "please change your default configuration as soon as possible "
+ "and we don't recommend you to use default tx-service-group's value provided by seata",
DEFAULT_TX_GROUP_OLD,
DEFAULT_TX_GROUP);
}
if (StringUtils.isNullOrEmpty(getApplicationId()) || StringUtils.isNullOrEmpty(getTxServiceGroup())) {
throw new IllegalArgumentException(
String.format("applicationId: %s, txServiceGroup: %s", getApplicationId(), getTxServiceGroup()));
}
// init TM
TMClient.init(getApplicationId(), getTxServiceGroup(), getAccessKey(), getSecretKey());
if (LOGGER.isInfoEnabled()) {
LOGGER.info(
"Transaction Manager Client is initialized. applicationId[{}] txServiceGroup[{}]",
getApplicationId(),
getTxServiceGroup());
}
// init RM
RMClient.init(getApplicationId(), getTxServiceGroup());
if (LOGGER.isInfoEnabled()) {
LOGGER.info(
"Resource Manager is initialized. applicationId[{}] txServiceGroup[{}]",
getApplicationId(),
getTxServiceGroup());
}View on GitHub (pinned to e01f97c6db)
Solutions
- In application.yml set seata.tx-service-group (required) and seata.application-id (or rely on spring.application.name): seata: { application-id: order-service, tx-service-group: my_tx_group }.
- If constructing GlobalTransactionScanner manually, pass both values: new GlobalTransactionScanner('order-service', 'my_tx_group').
- Check the active Spring profile actually contains the seata properties (missing profile = empty values).
- Ensure the properties are present before the scanner bean initializes — do not set them lazily via @PostConstruct of another bean.
Example fix
# before (application.yml)
spring:
application:
name: order-service
# no seata block -> applicationId/txServiceGroup empty
# after
spring:
application:
name: order-service
seata:
application-id: order-service
tx-service-group: my_tx_group Defensive patterns
Strategy: validation
Validate before calling
// Fail fast before the scanner initializes
@Value("${seata.application-id:${spring.application.name:}}") String applicationId;
@Value("${seata.tx-service-group:}") String txServiceGroup;
@PostConstruct
void checkSeataConfig() {
if (applicationId == null || applicationId.isBlank()
|| txServiceGroup == null || txServiceGroup.isBlank()) {
throw new IllegalStateException("seata.application-id (or spring.application.name) "
+ "and seata.tx-service-group must be set — got app='" + applicationId
+ "', group='" + txServiceGroup + "'");
}
} Prevention
- Put seata.tx-service-group and an explicit seata.application-id in every profile's application.yml from day one.
- Add a config lint in CI that fails if the seata block is missing in any deployed profile.
- When constructing GlobalTransactionScanner manually, always use the (applicationId, txServiceGroup) constructor.
- Note the default value changed in Seata 1.5 — never rely on the built-in default group.
When it happens
Trigger: Spring Boot app using seata-spring-boot-starter where application.yml lacks seata.application-id (or spring.application.name is absent and no explicit value set) and/or seata.tx-service-group; declaring the GlobalTransactionScanner bean manually with empty constructor args; setting the properties after the bean is already initialized.
Common situations: First-time Seata integration with missing 'seata.tx-service-group: my_tx_group' in application.yml; environment-specific profiles that omit the seata block; property renamed between versions (txServiceGroup constructor arg vs tx-service-group property); tests booting the context without the seata config.
Related errors
- datasource required not null!
- Apollo configuration initialized failed,please check the val
- config type can not be null
- Server start failed
- register TM failed. client version: %s,server version: %s, e
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/f2002cf7567532ae.
Report an issue: GitHub.