flowable/flowable-engine · error · FlowableException

no SMTP host is configured for the mail server for tenant {t

Error message

no SMTP host is configured for the mail server for tenant {tenantId}

What it means

Thrown during CmmnEngineConfiguration mail client initialization when a tenant-specific mail server entry exists but its SMTP host is null. Per-tenant mail sessions are built at startup and each configured tenant must have a resolvable host (unless a JNDI session is used).

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/CmmnEngineConfiguration.java:982

        Collection<String> tenantIds = new HashSet<>(mailSessionsJndi.keySet());
        tenantIds.addAll(mailServers.keySet());

        if (!tenantIds.isEmpty()) {
            Map<String, FlowableMailClient> mailClients = defaultMailClientProvider.getMailClients();
            MailServerInfo defaultMailServer = getDefaultMailServer();
            for (String tenantId : tenantIds) {
                if (mailClients.containsKey(tenantId)) {
                    continue;
                }
                String sessionJndi = mailSessionsJndi.get(tenantId);
                MailServerInfo tenantMailServer = mailServers.get(tenantId);
                if (sessionJndi != null) {
                    mailClients.put(tenantId, FlowableMailClientCreator.createSessionClient(sessionJndi, tenantMailServer, defaultMailServer));
                } else if (tenantMailServer != null) {
                    String host = tenantMailServer.getMailServerHost();
                    if (host == null) {
                        throw new FlowableException("no SMTP host is configured for the mail server for tenant " + tenantId);
                    }
                    mailClients.put(tenantId, FlowableMailClientCreator.createHostClient(host, tenantMailServer, defaultMailServer));
                }
            }
        }
    }
    public void initCmmnEngineAgendaFactory() {
        if (cmmnEngineAgendaFactory == null) {
            cmmnEngineAgendaFactory = new DefaultCmmnEngineAgendaFactory();
        }
    }

    @Override
    public void initCommandInvoker() {
        if (this.commandInvoker == null) {
            this.commandInvoker = new CmmnCommandInvoker(agendaOperationRunner, agendaOperationExecutionListeners);
        }
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Set the host for the tenant's MailServerInfo before engine start (setMailServerHost on the info or in the tenant config source)
  2. Configure a JNDI mail session for that tenant via mailSessionsJndi so host lookup is bypassed
  3. Remove the empty tenant entry if that tenant should fall back to the default mail server
  4. Validate tenant mail config at application startup (fail fast before CmmnEngineConfiguration.init)

Example fix

// before
MailServerInfo info = new MailServerInfo();
info.setMailServerUser("noreply");
mailServers.put("tenantA", info);

// after
MailServerInfo info = new MailServerInfo();
info.setMailServerHost("smtp.tenantA.example.com");
info.setMailServerPort(587);
mailServers.put("tenantA", info);
Defensive patterns

Strategy: validation

Validate before calling

for (Map.Entry<String, MailServerInfo> e : tenantMailServers.entrySet()) {
    if (e.getValue() == null || e.getValue().getMailServerHost() == null) {
        throw new IllegalStateException("Missing SMTP host for tenant " + e.getKey());
    }
}

Prevention

When it happens

Trigger: mailServers map contains an entry for tenantId with MailServerInfo.mailServerHost == null and no mailSessionsJndi entry for that tenant — e.g. setMailServers(Map) called with a partially filled MailServerInfo.

Common situations: Multi-tenant setup where one tenant's SMTP host property is missing or empty; programmatic setMailServers with a default-constructed MailServerInfo; tenant config loaded from DB/table with an empty host column.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/694bcc73d5e863d8. Report an issue: GitHub.