jstedfast/MailKit · error · ArgumentException
Control characters are prohibited.
Error message
Control characters are prohibited.
What it means
SaslMechanism.SaslPrep normalizes user strings per RFC 4013 (SASLprep). Control characters (U+0000-U+001F, U+007F) are prohibited in SASLprep output, so the method throws ArgumentException when the input string contains one. The library rejects the value early rather than sending an invalid identity to the server.
Solutions
- Trim and strip control characters from the string before passing it to the SASL mechanism (e.g. new string(s.Where(c => !char.IsControl(c)).ToArray())).
- Fix the source of the string (config file, env var, DB) so it does not include control characters, e.g. use .Trim() on values read from files.
- Catch ArgumentException and surface a clear 'invalid username/password' message to the user.
Example fix
// before var mech = new SaslMechanismLogin(userName); // userName contains "alice\n" // after var clean = new string(userName.Where(c => !char.IsControl(c)).ToArray()).Trim(); var mech = new SaslMechanismLogin(clean);
Defensive patterns
Strategy: validation
Validate before calling
static string SanitizeSaslString(string s) {
if (s == null) throw new ArgumentNullException(nameof(s));
var clean = new string(s.Where(c => !char.IsControl(c)).ToArray()).Trim();
return clean.Normalize(NormalizationForm.FormKC);
}
var mech = new SaslMechanismLogin(SanitizeSaslString(userName)); Try / catch
try {
var mech = new SaslMechanismLogin(userName);
} catch (ArgumentException) {
// reject credential: contains control/prohibited characters
} Prevention
- Trim all credential values read from files, env vars, or databases
- Strip char.IsControl characters before constructing SASL mechanisms
- Normalize user input with FormKC before authentication
When it happens
Trigger: Passing a username, authorization id, or other SASL identity containing control characters (e.g. a stray \0, \t, \r, or \n, often from config files or copy-paste) to a SaslMechanism constructor or credential property that runs SaslPrep.
Common situations: Credentials loaded from files with trailing newlines/CR, usernames read from environment variables or databases containing NUL bytes, passwords pasted from terminals with embedded control codes.
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
- One or more characters in the string are prohibited.
- A metadata tag identifier cannot be empty.
- All folders must be ImapFolders.
- Annotation entry paths must not end with '/'.
- Annotation entry paths must not end with '.'.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/1c41198f302b9e06.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Security/SaslMechanism.cs:742
public static string SaslPrep (string s)
{
if (s == null)
throw new ArgumentNullException (nameof (s));
if (s.Length == 0)
return s;
var builder = new StringBuilder (s.Length);
for (int i = 0; i < s.Length; i++) {
if (IsNonAsciiSpace (s[i])) {
// non-ASCII space characters [StringPrep, C.1.2] that can be
// mapped to SPACE (U+0020).
builder.Append (' ');
} else if (IsCommonlyMappedToNothing (s[i])) {
// the "commonly mapped to nothing" characters [StringPrep, B.1]
// that can be mapped to nothing.
} else if (char.IsControl (s[i])) {
throw new ArgumentException ("Control characters are prohibited.", nameof (s));
} else if (IsProhibited (s, i)) {
throw new ArgumentException ("One or more characters in the string are prohibited.", nameof (s));
} else {
builder.Append (s[i]);
}
}
return builder.ToString ().Normalize (NormalizationForm.FormKC);
}
internal static string GenerateEntropy (int n)
{
var entropy = new byte[n];
using (var rng = RandomNumberGenerator.Create ())
rng.GetBytes (entropy);
return Convert.ToBase64String (entropy);View on GitHub (pinned to 9d3859a785)