jstedfast/MailKit · error · SmtpProtocolException

Invalid status code returned by the server.

Error message

Invalid status code returned by the server.

What it means

ReadResponse validates each reply line's 3-digit status code: it must be >= 100 and be followed by a legal character ('-' for continuation or ' ' for final line). If the parsed value is out of range or the character after the code is illegal, MailKit throws SmtpProtocolException('Invalid status code returned by the server.').

Solutions

  1. Inspect the actual server reply via protocol logging (client with IProtocolLogger) to see the malformed line
  2. Fix the port/security-mode mismatch if the data is TLS garbage or another protocol
  3. Contact the mail server admin or upgrade server firmware/software if replies are genuinely invalid
  4. Catch SmtpProtocolException and retry against a different MX/server if available

Example fix

// before
client.Connect(host, 25, SecureSocketOptions.Auto); // proxy answers with junk
// after
using var logger = new ProtocolLogger(Console.OpenStandardError());
using var client = new SmtpClient(logger);
client.Connect(host, 587, SecureSocketOptions.StartTls);
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the server greeting and EHLO reply shape manually before use
// openssl s_client -connect host:465 -quiet  -> expect "220 ..."

Try / catch

try
{
    await client.SendAsync(message);
}
catch (SmtpProtocolException ex) when (ex.Message.Contains("status code"))
{
    // fall back to another MX or alert ops
}

Prevention

When it happens

Trigger: Server returns a reply line like '999x' or '12-' (value < 100) or a character other than '-', ' ' (space) right after the 3-digit code, e.g. '250X-message ...'.

Common situations: Non-compliant or misbehaving SMTP server/proxy; corrupted stream data from TLS/port mismatch; custom or load-balancer-generated replies; multi-line replies malformed by the server.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/675d0fab2c6a44e8. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Smtp/SmtpStream.cs:493

		static bool IsLegalAfterStatusCode (byte c)
		{
			return c == (byte) '-' || c == (byte) ' ' || c == (byte) '\r' || c == (byte) '\n';
		}

		bool ReadResponse (ByteArrayBuilder builder, ref bool newLine, ref bool more, ref int code)
		{
			do {
				int startIndex = inputIndex;

				if (newLine) {
					if (inputIndex + 3 < inputEnd) {
						if (!TryParseStatusCode (input, inputIndex, out int value))
							throw new SmtpProtocolException ("Unable to parse status code returned by the server.");

						inputIndex += 3;

						if (value < 100 || !IsLegalAfterStatusCode (input[inputIndex]))
							throw new SmtpProtocolException ("Invalid status code returned by the server.");

						if (code == 0) {
							code = value;
						} else if (value != code) {
							throw new SmtpProtocolException ("The status codes returned by the server did not match.");
						}

						newLine = false;

						more = input[inputIndex] == (byte) '-';
						if (more || input[inputIndex] == (byte) ' ')
							inputIndex++;

						startIndex = inputIndex;
					} else {
						// Need input.
						return true;
					}

View on GitHub (pinned to 9d3859a785)