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

  1. 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 }.
  2. If constructing GlobalTransactionScanner manually, pass both values: new GlobalTransactionScanner('order-service', 'my_tx_group').
  3. Check the active Spring profile actually contains the seata properties (missing profile = empty values).
  4. 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

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


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