jstedfast/MailKit · error · InvalidOperationException

Compression must be enabled before selecting a folder.

Error message

Compression must be enabled before selecting a folder.

What it means

IMAP compression changes the connection's encoding, so it must be negotiated while the session is still unselected (before any folder is open). QueueCompressCommand throws InvalidOperationException if engine.State is Selected or beyond, because compressing mid-selection would corrupt the stream state.

Solutions

  1. Call Compress() immediately after Connect/Authenticate and before opening any folder
  2. Reorder your setup: Connect -> Authenticate -> Compress -> OpenFolder
  3. If compression is needed later, disconnect, reconnect, compress, then select

Example fix

// before
await client.ConnectAsync(...);
await client.AuthenticateAsync(...);
var folder = await client.GetFolderAsync("INBOX");
await folder.OpenAsync(FolderAccess.ReadWrite);
client.Compress(); // throws - folder already selected
// after
await client.ConnectAsync(...);
await client.AuthenticateAsync(...);
client.Compress();
var folder = await client.GetFolderAsync("INBOX");
await folder.OpenAsync(FolderAccess.ReadWrite);
Defensive patterns

Strategy: validation

Validate before calling

if (client is ImapClient imap && imap.State == ImapEngineState.Selected)
	throw new InvalidOperationException("Call Compress before opening a folder.");

Try / catch

try {
	client.Compress();
} catch (InvalidOperationException) {
	// reconnect and compress before selecting, or skip compression
}

Prevention

When it happens

Trigger: Calling client.Compress() after a folder has already been selected/opened (e.g. after GetFolder(...).Open(...)) on the same connection.

Common situations: Adding compression to an existing code path after mailbox operations; enabling compression in the middle of a long-lived session that already opened INBOX; copy-pasting Compress() after folder-opening boilerplate.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at MailKit/Net/Imap/ImapClient.cs:295

			if (!valid) {
				// Note: The SslHandshakeException.Create() method will nullify this once it's done using it.
				sslValidationInfo = new SslCertificateValidationInfo (host, certificate, chain, sslPolicyErrors);
			}

			return valid;
		}

		ImapCommand QueueCompressCommand (CancellationToken cancellationToken)
		{
			CheckDisposed ();
			CheckConnected ();

			if ((engine.Capabilities & ImapCapabilities.Compress) == 0)
				throw new NotSupportedException ("The IMAP server does not support the COMPRESS extension.");

			if (engine.State >= ImapEngineState.Selected)
				throw new InvalidOperationException ("Compression must be enabled before selecting a folder.");

#if MAILKIT_LITE
			throw new NotSupportedException ("MailKitLite does not support the COMPRESS extension.");
#else
			return engine.QueueCommand (cancellationToken, null, "COMPRESS DEFLATE\r\n");
#endif
		}

		void ProcessCompressResponse (ImapCommand ic)
		{
#if !MAILKIT_LITE
			if (ic.Response != ImapCommandResponse.Ok) {
				for (int i = 0; i < ic.RespCodes.Count; i++) {
					if (ic.RespCodes[i].Type == ImapResponseCodeType.CompressionActive)
						return;
				}

				throw ImapCommandException.Create ("COMPRESS", ic);

View on GitHub (pinned to 9d3859a785)