quarkusio/quarkus · error · IllegalArgumentException

Unable to send an email, an email address is invalid

Error message

Unable to send an email, an email address is invalid

What it means

Identical to the previous case but thrown when logInvalidRecipients is false: the library deliberately hides the invalid address from the exception and logs only "an email address is invalid", since exception messages could leak recipient data. The original parsing exception is swallowed (only a sanitized warning is logged).

Source

Thrown at extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/MutinyMailerImpl.java:251

                new EmailAddress(email);
            }
            for (String email : cc) {
                new EmailAddress(email);
            }
            for (String email : bcc) {
                new EmailAddress(email);
            }
        } catch (IllegalArgumentException e) {
            // One of the email addresses is invalid
            if (logInvalidRecipients) {
                // We are allowed to log the invalid email address
                // The exception message contains the invalid email address.
                LOGGER.warn("Unable to send an email", e);
                throw new IllegalArgumentException("Unable to send an email", e);
            } else {
                // Do not print the invalid email address.
                LOGGER.warn("Unable to send an email, an email address is invalid");
                throw new IllegalArgumentException("Unable to send an email, an email address is invalid");
            }
        }
    }

    private MultiMap toMultimap(Map<String, List<String>> headers) {
        MultiMap mm = MultiMap.caseInsensitiveMultiMap();
        headers.forEach(mm::add);
        return mm;
    }

    private Uni<MailAttachment> toMailAttachment(Attachment attachment) {
        MailAttachment attach = MailAttachment.create();
        attach.setName(attachment.getName());
        attach.setContentId(attachment.getContentId());
        attach.setDescription(attachment.getDescription());
        attach.setDisposition(attachment.getDisposition());
        attach.setContentType(attachment.getContentType());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Temporarily set quarkus.mailer.log-invalid-recipients=true in dev/test to see the offending address in the log and the exception cause.
  2. Pre-validate addresses in your own code so the failure points at the exact input before calling send().
  3. Sanitize inputs: trim, strip surrounding brackets/commas, verify domain presence.
  4. Add structured logging around your send call capturing the recipient list you attempted.

Example fix

// before (which address failed is hidden)
mailer.send(Mail.withText(rawRecipient, subject, body));

// after (validate first, log the rejected value yourself)
if (!EMAIL.matcher(rawRecipient.trim()).matches()) {
    LOG.warnf("Rejecting invalid recipient: %s", rawRecipient);
    return;
}
mailer.send(Mail.withText(rawRecipient.trim(), subject, body));
Defensive patterns

Strategy: try-catch

Validate before calling

List<String> invalid = Stream.of(to, cc, bcc, from)
        .filter(Objects::nonNull)
        .filter(a -> !isValidEmail(a))
        .toList();
if (!invalid.isEmpty()) {
    LOG.warnf("Rejecting send; invalid addresses: %s", invalid);
    return;
}

Type guard

static boolean isValidEmail(String address) {
    return address != null && !address.isBlank() && EMAIL.matcher(address.trim()).matches();
}

Try / catch

try {
    mailer.send(mail).await().indefinitely();
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("Unable to send an email, an email address is invalid")) {
        LOG.warn("An address failed validation; enable quarkus.mailer.log-invalid-recipients locally to see it");
    }
    throw e;
}

Prevention

When it happens

Trigger: Sending a mail with any malformed address while quarkus.mailer.log-invalid-recipients is false (the default), so validate() throws the sanitized IllegalArgumentException.

Common situations: Production hardening hides which address failed, making debugging hard; batch sends where one bad address aborts the send; data migrations importing addresses with trailing commas or brackets.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/4ffec55e5e11422f. Report an issue: GitHub.