flowable/flowable-engine · error · FlowableMailException

Invalid email

Error message

Invalid email

What it means

createInternetAddress converts the given string to an ASCII email, constructs a jakarta.mail InternetAddress and calls validate(). If validation raises AddressException, the client wraps it in FlowableMailException('Invalid email'). It means the supplied string is not a syntactically valid email address.

Source

Thrown at modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java:211

        }
        if (!newRecipients.isEmpty()) {
            for (String t : newRecipients) {
                try {
                    message.addRecipient(recipientType, createInternetAddress(t));
                } catch (MessagingException e) {
                    throw new FlowableMailException("Could not add " + t + " as " + recipientType + " recipient", e);
                }
            }
        }
    }

    protected InternetAddress createInternetAddress(String email) {
        try {
            InternetAddress address = new InternetAddress(toASCIIEmail(email));
            address.validate();
            return address;
        } catch (AddressException e) {
            throw new FlowableMailException("Invalid email", e);
        }
    }

    protected String toASCIIEmail(String email) {
        int atIndex = email.indexOf('@');
        if (atIndex < 0) {
            return email;
        }

        // localPart@domainPart
        return email.substring(0, atIndex) + '@' + IDN.toASCII(email.substring(atIndex + 1));

    }

    protected void setFrom(MimeMessage message, String from) {
        String fromAddress;

        if (from != null) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Fix the offending address string; validate with a regex or InternetAddress(email).validate() before sending.
  2. Trim whitespace and strip display-name decorations, passing only the bare address.
  3. If sending to multiple addresses, split on commas and add each separately.
  4. For internationalized addresses, ensure IDN/punycode conversion of the domain is performed before calling the client.

Example fix

// before
request.setFrom("Flowable Bot <no-reply@example.com>");

// after
request.setFrom("no-reply@example.com"); // bare, validated address
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidEmail(String s) {
    if (s == null) return false;
    try { new jakarta.mail.internet.InternetAddress(s.trim(), true).validate(); return true; }
    catch (jakarta.mail.internet.AddressException e) { return false; }
}

Type guard

boolean isPlainAddress(String s) { return s != null && s.matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"); }

Try / catch

try { request.setFrom(from); } catch (FlowableMailException e) { if (e.getMessage().equals("Invalid email")) { throw new InvalidMailAddressException(from); } throw e; }

Prevention

When it happens

Trigger: Calling setFrom or any add*Recipient with a string that fails InternetAddress validation — missing '@', illegal characters, malformed domain, or characters that cannot be converted to ASCII by toASCIIEmail.

Common situations: Free-text user input used as email address; 'Name <email>' or comma-separated multi-address strings passed to single-address APIs; internationalized addresses where IDN conversion fails; trailing whitespace or newlines from CSV import.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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