flowable/flowable-engine · error · FlowableMailException
Could not create text-only email
Error message
Could not create text-only email
What it means
When the email is text-only (html is null and there are no attachments), setContent() calls mimeMessage.setText(text, charset). A MessagingException from setText is wrapped as FlowableMailException "Could not create text-only email". It means Jakarta Mail could not set the plain-text body on the freshly built MimeMessage.
Solutions
- Check the nested MessagingException cause for 'unsupported encoding' details
- Validate the charset value passed via the mail task / MailMessage (use standard names: UTF-8, ISO-8859-1)
- Ensure the JVM supports the charset (Charset.isSupported(charset))
- Use html content instead of plain text if the charset issue persists
Example fix
// before <flowable:field name="text"> <flowable:string>hello</flowable:string> </flowable:field> <flowable:field name="charSet"><flowable:string>utf_8</flowable:string></flowable:field> // after <flowable:field name="charSet"><flowable:string>UTF-8</flowable:string></flowable:field>
Defensive patterns
Strategy: validation
Validate before calling
if (charset != null && !java.nio.charset.Charset.isSupported(charset)) {
throw new IllegalArgumentException("Unsupported charset: " + charset);
} Try / catch
try {
mailClient.send(mailMessage);
} catch (FlowableMailException e) {
if (e.getMessage().contains("Could not create text-only email")) {
log.error("setText failed — check charset in mail config", e.getCause());
}
} Prevention
- Use canonical charset names (UTF-8, ISO-8859-1) in mail task config
- Assert Charset.isSupported(charset) at startup
- Prefer HTML content if charset edge cases keep occurring
When it happens
Trigger: Sending a plain-text-only email (no html, no attachments) where MimeMessage.setText(text, charset) throws — typically due to an unsupported charset name or a MessagingException from the MIME part internals.
Common situations: Passing an invalid/unknown charset string (e.g. a typo like 'utf_8' or a localized name not recognized by the JDK); misconfigured mail server charset settings feeding an invalid charset into the mail task.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Could not encode attachment file name
- Failed to add body part
- Failed to create multi part email
- Failed to set send date
- Could not add as recipient
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ccd4cf98dbfbf369.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-mail/src/main/java/org/flowable/mail/common/impl/jakarta/mail/JakartaMailFlowableMailClient.java:264
}
} catch (MessagingException e) {
throw new FlowableMailException("Failed to set send date", e);
}
}
protected void setContent(MimeMessage mimeMessage, MailMessage message, String charset) {
String text = message.getPlainContent();
String html = message.getHtmlContent();
Collection<DataSource> attachments = message.getAttachments();
boolean attachmentsExists = attachments != null && !attachments.isEmpty();
if (html == null && text == null) {
throw new FlowableIllegalArgumentException("'html' or 'text' is required to be defined when sending an email");
}
if (html == null && !attachmentsExists) {
try {
mimeMessage.setText(text, charset);
} catch (MessagingException e) {
throw new FlowableMailException("Could not create text-only email", e);
}
} else {
try {
mimeMessage.setContent(createMultiPartContent(text, html, charset, attachments));
} catch (MessagingException e) {
throw new FlowableMailException("Failed to create multi part email", e);
}
}
}
protected MimeMultipart createMultiPartContent(String text, String html, String charset, Collection<DataSource> attachments) throws MessagingException {
boolean attachmentsExists = attachments != null && !attachments.isEmpty();
MimeMultipart rootContainer = new MimeMultipart();
MimeMultipart bodyContainer = rootContainer;
rootContainer.setSubType("mixed");
View on GitHub (pinned to d6d39ce1c6)