SonarSource/sonarqube · error · IllegalArgumentException
Address contains invalid character: 0x%02x
Error message
Address contains invalid character: 0x%02x
What it means
EmailNotificationChannel.validateAddress rejects email addresses containing carriage return or line feed characters, which would enable SMTP header injection. It throws IllegalArgumentException with the offending byte's hex value.
Solutions
- Sanitize the user's email field: strip/trim CR and LF characters at the source (user record, LDAP sync, or API input).
- Check how the offending address was provisioned and fix the upstream data (AD attribute, CSV import).
- Reject invalid emails at user-creation validation time with a clear message.
- After fixing the user data, resend/resume notifications.
Example fix
// before
user.setEmail(ldapAttribute); // may contain "a@b.com\n"
// after
user.setEmail(ldapAttribute.replaceAll("[\\r\\n]", "").trim()); Defensive patterns
Strategy: validation
Validate before calling
boolean isValidEmail(String email) { return email != null && !email.chars().anyMatch(c -> c == '\r' || c == '\n'); } Try / catch
try { emailChannel.deliver(payload); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Address contains invalid character")) { log.warn("Skipping notification: bad email address"); return; } throw e; } Prevention
- Sanitize emails at ingestion (LDAP sync, CSV import, API)
- Trim and strip CR/LF from all user emails on write
- Add user-creation validation rejecting newlines in email
When it happens
Trigger: Adding a user whose email field contains \r or \n (e.g. pasted multi-line value, Ldap/SAML attribute with newlines), then sending a notification via setToAndFrom.
Common situations: User emails imported from LDAP/AD or CSV with trailing newline; API call creating users with embedded newlines in email; template bugs concatenating addresses with newlines.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Provided JSON is invalid
- a JVM option can't be empty and must start with '-'. The…
- allowAllGroups can only be enabled when Auto-provisioning…
- allowAllGroups cannot be enabled when the GitLab URL is…
- allowedGroups cannot be empty when Auto-provisioning is…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/e27175439a38c5ae.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java:279
}
private void setToAndFrom(Email email, EmailMessage emailMessage) throws EmailException {
String fromName = configuration.getFromName();
String from = StringUtils.isBlank(emailMessage.getFrom()) ? fromName : (emailMessage.getFrom() + " (" + fromName + ")");
email.setFrom(configuration.getFrom(), from);
validateAddress(emailMessage.getTo());
email.addTo(emailMessage.getTo(), " ");
}
private static void validateAddress(String mailAddress) {
//validating that the email address does not contain CR or LF characters to prevent SMTP injection
final byte CR = '\r';
final byte LF = '\n';
for (char aChar : mailAddress.toCharArray()) {
byte b = (byte) aChar;
if (b == LF || b == CR) {
throw new IllegalArgumentException("Address contains invalid character: " + String.format("0x%02x", b));
}
}
}
@CheckForNull
private String resolveHost() {
try {
return new URI(server.getPublicRootUrl()).getHost();
} catch (URISyntaxException e) {
// ignore
return null;
}
}
private void setHeaders(Email email, EmailMessage emailMessage, @CheckForNull String host) {
// Set general information
email.setCharset("UTF-8");
if (StringUtils.isNotBlank(host)) {View on GitHub (pinned to 184c821202)