flowable/flowable-engine · error · FlowableMailException

Could not add as recipient

Error message

Could not add  as  recipient

What it means

addRecipient adds each recipient (To/Cc/Bcc) to the MimeMessage; if message.addRecipient throws MessagingException for a specific address, the client wraps it in FlowableMailException naming the offending address and recipient type. The message text is 'Could not add <address> as <TYPE> recipient'.

Source

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

    protected void addBcc(MimeMessage message, Collection<String> bcc) {
        addRecipient(message, bcc, Message.RecipientType.BCC);
    }

    protected void addRecipient(MimeMessage message, Collection<String> recipients, Message.RecipientType recipientType) {
        if (recipients == null || recipients.isEmpty()) {
            return;
        }
        Collection<String> newRecipients = recipients;
        Collection<String> forceRecipients = defaultsConfiguration.forceTo();
        if (forceRecipients != null && !forceRecipients.isEmpty()) {
            newRecipients = forceRecipients;
        }
        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) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Read the exception message: it names the exact address that failed; remove or fix that entry in the recipient list.
  2. Validate every address (regex or InternetAddress.validate()) before adding recipients.
  3. Split batch sends so one bad recipient does not abort the whole email; handle per-recipient failures.
  4. Check for whitespace/newlines embedded in addresses coming from user data or databases.

Example fix

// before
mailClient.addTo(SendMailRequest.builder(), List.of("a@x.com", "b at y.com"));

// after
List<String> valid = recipients.stream()
    .filter(r -> r != null && r.matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"))
    .collect(Collectors.toList());
mailClient.addTo(SendMailRequest.builder(), valid);
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern EMAIL = Pattern.compile("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
List<String> validRecipients = recipients.stream().filter(r -> r != null && EMAIL.matcher(r.trim()).matches()).toList();

Type guard

boolean isValidRecipient(String a) { return a != null && EMAIL.matcher(a.trim()).matches(); }

Try / catch

try { builder.addTo(req, recipients); } catch (FlowableMailException e) { log.error("bad recipient: " + e.getMessage(), e.getCause()); throw e; }

Prevention

When it happens

Trigger: Calling addTo/addCc/addBcc with an address string for which createInternetAddress succeeds parsing but Message.addRecipient fails, or an underlying addRecipient MessagingException during message assembly.

Common situations: Recipient lists loaded from external systems containing malformed or duplicate entries; addresses with illegal characters that pass initial parsing but fail at add time; group/distribution addresses the mail provider rejects.

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/e964b0b68116d68a. Report an issue: GitHub.