jstedfast/MailKit · error · ArgumentOutOfRangeException
Specified argument was out of the range of valid values…
Error message
Specified argument was out of the range of valid values. (Parameter 'port')
What it means
MailService.ConnectAsync validates the port argument before opening a connection. A ArgumentOutOfRangeException is thrown when port is negative or greater than 65535, since those are not valid TCP port values. This is a fail-fast guard so you never attempt a network connection with an unusable port.
Solutions
- Verify the port number is within 0-65535 before calling ConnectAsync
- Fix the configuration value or default that produced the invalid port
- If a port variable may be 'unset', use -1 only with APIs that accept it and pass a valid port here
- Clamp or validate parsed user input before constructing the connection call
Example fix
// before
int port = int.Parse(config["Port"]); // -1 when missing
await client.ConnectAsync(host, port);
// after
int port = int.Parse(config["Port"]);
if (port < 0 || port > 65535) throw new InvalidOperationException("SMTP port is not configured");
await client.ConnectAsync(host, port); Defensive patterns
Strategy: validation
Validate before calling
if (port < 0 || port > 65535) throw new ArgumentOutOfRangeException(nameof(port), port, "Port must be between 0 and 65535"); await client.ConnectAsync(host, port, cancellationToken);
Type guard
bool IsValidPort(int port) => port >= 0 && port <= 65535;
Try / catch
try { await client.ConnectAsync(host, port, ct); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "port") { logger.LogError(ex, "Invalid port {Port} for host {Host}", port, host); throw new ConfigurationException("Invalid mail server port", ex); } Prevention
- Validate port values at config-load time, before any connection attempt
- Never use -1 or other sentinels as a port value for ConnectAsync
- Parse ports with TryParse and range-check the result
- Keep port values as dedicated validated types in your config layer
When it happens
Trigger: Calling ConnectAsync(host, port) or ConnectAsync(host, port, useSsl) with a port < 0 or port > 65535, e.g. a port parsed from config as -1, a missing config defaulting to 0-minus, or an integer overflow when combining host:port.
Common situations: Config files with an unset/placeholder port (e.g. -1 meaning 'unset'), string parsing that yields a sentinel value, or a user typo like 99999 for an SMTP/IMAP port.
Related errors
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/bc14dc1791227831.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/MailService.cs:1021
/// <exception cref="System.Net.Sockets.SocketException">
/// A socket error occurred trying to connect to the remote host.
/// </exception>
/// <exception cref="System.IO.IOException">
/// An I/O error occurred.
/// </exception>
/// <exception cref="ProtocolException">
/// A protocol error occurred.
/// </exception>
public Task ConnectAsync (string host, int port, bool useSsl, CancellationToken cancellationToken = default)
{
if (host == null)
throw new ArgumentNullException (nameof (host));
if (host.Length == 0)
throw new ArgumentException ("The host name cannot be empty.", nameof (host));
if (port < 0 || port > 65535)
throw new ArgumentOutOfRangeException (nameof (port));
return ConnectAsync (host, port, useSsl ? SecureSocketOptions.SslOnConnect : SecureSocketOptions.StartTlsWhenAvailable, cancellationToken);
}
/// <summary>
/// Authenticate using the supplied credentials.
/// </summary>
/// <remarks>
/// <para>Authenticates using the supplied credentials.</para>
/// <para>If the server supports one or more SASL authentication mechanisms, then
/// the SASL mechanisms that both the client and server support (not including any
/// OAUTH mechanisms) are tried in order of greatest security to weakest security.
/// Once a SASL authentication mechanism is found that both client and server support,
/// the credentials are used to authenticate.</para>
/// <para>If the server does not support SASL or if no common SASL mechanisms
/// can be found, then the default login command is used as a fallback.</para>
/// <note type="tip">To prevent the usage of certain authentication mechanisms,
/// simply remove them from the <see cref="AuthenticationMechanisms"/> hash setView on GitHub (pinned to 9d3859a785)