flowable/flowable-engine · error · FlowableMailException

Failed to create mime message

Error message

Failed to create mime message

What it means

JakartaMailFlowableMailClient.prepareRequest builds a jakarta.mail MimeMessage from a SendMailRequest. Any MessagingException raised while assembling the message (invalid headers, bad addresses, malformed content) is wrapped in FlowableMailException with the message 'Failed to create mime message'.

Source

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

    private static final Duration SOCKET_TIMEOUT = Duration.ofSeconds(60);
    private static final Duration SOCKET_CONNECTION_TIMEOUT = Duration.ofSeconds(60);

    protected final MailServerConfiguration serverConfiguration;
    protected final MailDefaultsConfiguration defaultsConfiguration;

    public JakartaMailFlowableMailClient(MailServerConfiguration serverConfiguration, MailDefaultsConfiguration defaultsConfiguration) {
        this.serverConfiguration = serverConfiguration;
        this.defaultsConfiguration = defaultsConfiguration;
    }

    @Override
    public ExecutableSendMailRequest prepareRequest(SendMailRequest request) {
        Session session = createSession();
        try {
            MimeMessage mimeMessage = createMimeMessage(request, session);
            return new JakartaMailSendMailRequest(mimeMessage);
        } catch (MessagingException e) {
            throw new FlowableMailException("Failed to create mime message", e);
        }
    }

    protected MimeMessage createMimeMessage(SendMailRequest request, Session session) throws MessagingException {
        MimeMessage mimeMessage = new MimeMessage(session);

        MailMessage message = request.message();
        Charset charset = getCharset(message);
        setContent(mimeMessage, message, charset != null ? charset.name() : null);
        setSubject(mimeMessage, message.getSubject(), charset);
        addHeaders(mimeMessage, message.getHeaders(), charset);
        addTo(mimeMessage, message.getTo());
        addCc(mimeMessage, message.getCc());
        addBcc(mimeMessage, message.getBcc());

        setFrom(mimeMessage, message.getFrom());
        setSentDate(mimeMessage);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the wrapped MessagingException cause for the exact failure (e.g. address or header problem).
  2. Validate all email addresses and header values in the SendMailRequest before sending.
  3. Check the configured charset and any custom headers/subject for illegal characters (CR/LF, non-ASCII where unsupported).
  4. Sanitize or drop offending fields and retry the request.

Example fix

// before
mailClient.sendMail(SendMailRequest.builder().to(rawUserInput).subject(subject).build());

// after
String to = sanitizeAndValidateEmail(rawUserInput); // trim, check pattern, no CR/LF
if (to != null) {
    mailClient.sendMail(SendMailRequest.builder().to(to).subject(subject).build());
}
Defensive patterns

Strategy: try-catch

Validate before calling

private static final Pattern EMAIL = Pattern.compile("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
boolean validEmail(String s) { return s != null && EMAIL.matcher(s.trim()).matches(); }

Type guard

boolean isSendable(SendMailRequest r) { return r != null && r.getTo() != null && r.getTo().stream().allMatch(this::validEmail); }

Try / catch

try { client.sendMail(request); } catch (FlowableMailException e) { log.error("mime message creation failed", e.getCause()); throw new MailSendException("invalid mail request", e); }

Prevention

When it happens

Trigger: Calling the mail client's send/prepareRequest path where createMimeMessage throws MessagingException — e.g. illegal header values, invalid recipient addresses from addRecipient/setFrom, or unsupported charset/content settings.

Common situations: Emails with dynamically generated recipients or subject headers containing illegal characters or newlines; bad addresses in data coming from users or a database; charset configuration that jakarta.mail rejects.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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