{"record":{"id":"c609d33d4ab9fe4a","repo":"jstedfast/MailKit","slug":"the-smtpclient-must-be-connected-before-you-can-send","errorCode":null,"errorMessage":"The SmtpClient must be connected before you can send commands.","messagePattern":"The SmtpClient must be connected before you can send commands\\.","errorType":"exception","errorClass":"ServiceNotConnectedException","httpStatus":null,"severity":"error","filePath":"MailKit/Net/Smtp/AsyncSmtpClient.cs","lineNumber":132,"sourceCode":"\t\t/// </exception>\n\t\t/// <exception cref=\"System.OperationCanceledException\">\n\t\t/// The operation has been canceled.\n\t\t/// </exception>\n\t\t/// <exception cref=\"System.IO.IOException\">\n\t\t/// An I/O error occurred.\n\t\t/// </exception>\n\t\t/// <exception cref=\"SmtpProtocolException\">\n\t\t/// An SMTP protocol exception occurred.\n\t\t/// </exception>\n\t\tprotected Task<SmtpResponse> SendCommandAsync (string command, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tif (command == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (command));\n\n\t\t\tCheckDisposed ();\n\n\t\t\tif (!IsConnected)\n\t\t\t\tthrow new ServiceNotConnectedException (\"The SmtpClient must be connected before you can send commands.\");\n\n\t\t\tif (!command.EndsWith (\"\\r\\n\", StringComparison.Ordinal))\n\t\t\t\tcommand += \"\\r\\n\";\n\n\t\t\treturn SendCommandInternalAsync (command, cancellationToken);\n\t\t}\n\n\t\tTask<SmtpResponse> SendEhloAsync (bool connecting, string helo, CancellationToken cancellationToken)\n\t\t{\n\t\t\tvar command = CreateEhloCommand (helo);\n\n\t\t\tif (connecting)\n\t\t\t\treturn Stream!.SendCommandAsync (command, cancellationToken);\n\n\t\t\treturn SendCommandInternalAsync (command, cancellationToken);\n\t\t}\n\n\t\tasync Task EhloAsync (bool connecting, CancellationToken cancellationToken)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Net/Smtp/AsyncSmtpClient.cs#L114-L150","documentation":"AsyncSmtpClient.SendCommandAsync validates state before sending a raw protocol command. If the client has not completed a connection (IsConnected is false) it throws ServiceNotConnectedException with this message, since there is no protocol stream to write to.","triggerScenarios":"Calling SendCommandAsync before ConnectAsync, or after the connection dropped, was disconnected via DisconnectAsync, or failed during the SMTP handshake.","commonSituations":"Sending custom commands at app startup before the connection task completes; reusing a client instance after a previous send failed and closed the session.","solutions":["Await ConnectAsync (with host, port and options) before calling SendCommandAsync.","Check the IsConnected property before sending raw commands.","If the connection dropped, reconnect (ConnectAsync) before issuing commands.","Catch ServiceNotConnectedException and trigger reconnection logic."],"exampleFix":"// before\nawait client.SendCommandAsync(\"NOOP\\r\\n\");\n// after\nif (!client.IsConnected)\n    await client.ConnectAsync(\"smtp.example.com\", 465, SecureSocketOptions.SslOnConnect);\nawait client.SendCommandAsync(\"NOOP\\r\\n\");","handlingStrategy":"validation","validationCode":"if (client == null || client.IsDisposed) throw new ObjectDisposedException(nameof(client));\nif (!client.IsConnected)\n    await client.ConnectAsync(smtpHost, smtpPort, SecureSocketOptions.StartTls);","typeGuard":"bool CanSendCommands(AsyncSmtpClient c) => c != null && !c.IsDisposed && c.IsConnected;","tryCatchPattern":"try {\n    var resp = await client.SendCommandAsync(\"NOOP\\r\\n\");\n} catch (ServiceNotConnectedException) {\n    await client.ConnectAsync(smtpHost, smtpPort, SecureSocketOptions.Auto);\n    // retry the command\n}","preventionTips":["Always await ConnectAsync before issuing any protocol commands","Check IsConnected before each custom command","Wrap session usage in a connect/send/disconnect lifecycle, not ad-hoc commands","Reconnect on ServiceNotConnectedException instead of retrying the command"],"tags":["smtp","connection-state","async"],"backgroundTag":"invalid-state-transition","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}