jstedfast/MailKit · error · IOException

Error inflating:

Error message

Error inflating: 

What it means

Read() throws IOException("Error inflating: " + zIn.msg) when JZlib's inflate() returns a status other than Z_OK (and the special end-of-stream Z_BUF_ERROR case is excluded). zIn.msg carries zlib's description of the corrupted or unexpected compressed data.

Solutions

  1. Inspect zIn.msg / the IOException message to identify the zlib failure (data error, need dictionary, etc.).
  2. Verify the inner stream actually contains zlib data and was not corrupted or truncated; reconnect and reissue the COMPRESS command.
  3. Ensure you did not interleave raw writes/reads on the same socket outside CompressedStream, which desynchronizes the deflate/inflate state.
  4. Regenerate or re-fetch the compressed data; if the source data is bad, the stream cannot recover.

Example fix

// before
int n = compressedStream.Read(buffer, 0, buffer.Length); // IOException: Error inflating
// after
try {
    int n = compressedStream.Read(buffer, 0, buffer.Length);
} catch (IOException ex) when (ex.Message.StartsWith("Error inflating")) {
    // inner stream data is corrupt/not zlib - reconnect and restart COMPRESS
    ReconnectAndRecompress();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before reading, sanity-check the source is zlib data (RFC1950 header 0x78)
int first = innerStream.ReadByte();
if (first != 0x78) throw new InvalidDataException("Inner stream is not zlib-compressed.");
// (also keep a copy so the byte can be pushed back / stream recreated)

Type guard

static bool IsZlibHeader(Stream s) {
    int b = s.ReadByte();
    if (b < 0) return false;
    s.Position = s.CanSeek ? 0 : 0; // rewind only if seekable
    return (b & 0x0F) == 8; // CMF: deflate method
}

Try / catch

try {
    int n = compressedStream.Read(buffer, 0, buffer.Length);
} catch (IOException ex) when (ex.Message.StartsWith("Error inflating")) {
    // corrupt or non-zlib data: cannot recover inflate state; reconnect/restart session
    logger.LogError(ex, "Inflate failure: {Msg}", ex.Message);
    await ReconnectAsync();
}

Prevention

When it happens

Trigger: Calling CompressedStream.Read when the underlying stream yields bytes that fail zlib inflation: corrupt/truncated compressed data, wrong compression window size, reading a stream not actually zlib-compressed, or protocol desync (e.g. an IMAP server response that is not compressed payload).

Common situations: IMAP COMPRESS sessions where the server sent a literal or untagged response that was not compressed, network truncation mid-stream, feeding a raw (uncompressed) stream into CompressedStream, zlib version/format mismatch.

Related errors


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

Appendix: source

Thrown at MailKit/CompressedStream.cs:213

			do {
				if (zIn.avail_in == 0 && !eos) {
					zIn.avail_in = InnerStream.Read (zIn.next_in, 0, zIn.next_in.Length);

					eos = zIn.avail_in == 0;
					zIn.next_in_index = 0;
				}

				int retval = zIn.inflate (JZlib.Z_FULL_FLUSH);

				if (retval == JZlib.Z_STREAM_END)
					break;

				if (eos && retval == JZlib.Z_BUF_ERROR)
					return 0;

				if (retval != JZlib.Z_OK)
					throw new IOException ("Error inflating: " + zIn.msg);
			} while (zIn.avail_out == count);

			return count - zIn.avail_out;
		}

		/// <summary>
		/// Reads a sequence of bytes from the stream and advances the position
		/// within the stream by the number of bytes read.
		/// </summary>
		/// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many
		/// bytes are not currently available, or zero (0) if the end of the stream has been reached.</returns>
		/// <param name="buffer">The buffer.</param>
		/// <param name="offset">The buffer offset.</param>
		/// <param name="count">The number of bytes to read.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="buffer"/> is <see langword="null" />.
		/// </exception>

View on GitHub (pinned to 9d3859a785)