jstedfast/MailKit · error · ArgumentException
The destination folder does not belong to this ImapClient.
Error message
The destination folder does not belong to this ImapClient.
What it means
This ArgumentException comes from ImapFolder.CheckValidDestination when CopyTo or MoveTo receives a destination folder that is either not an ImapFolder or belongs to a different ImapClient instance (different Engine). An IMAP COPY/MOVE command can only target mailboxes on the same server session.
Solutions
- To move between servers/clients, copy by message content: GetMessage from source and AppendMessage to destination folder, then mark source as deleted and expunge.
- Ensure destination is a folder from the SAME ImapClient instance (client.GetFolder(...) of the same connection).
- If reconnecting, re-fetch folder references from the new ImapClient rather than reusing stale ones.
- Check destination is ImapFolder and its Engine matches before calling CopyTo/MoveTo.
Example fix
// before
var dest = otherClient.GetFolder("Archive");
inbox.MoveTo(dest);
// after
var dest = client.GetFolder("Archive");
dest.Open(FolderAccess.ReadWrite);
inbox.MoveTo(dest);
// cross-client alternative:
// dest.AppendMessage(inbox.GetMessage(uid)); Defensive patterns
Strategy: type-guard
Validate before calling
if (destination is not ImapFolder t || !ReferenceEquals(t.Engine, ((ImapFolder)folder).Engine)) throw new InvalidOperationException("destination must belong to the same client"); Type guard
bool IsSameClientDestination(IMailFolder src, IMailFolder dest) => src is ImapFolder s && dest is ImapFolder d && ReferenceEquals(s.Engine, d.Engine);
Try / catch
try { inbox.MoveTo(dest); } catch (ArgumentException) { MoveViaAppend(inbox, dest); } Prevention
- Only pass folders obtained from the same ImapClient instance to CopyTo/MoveTo.
- Re-fetch folder references from the current client after any reconnect.
- For cross-account/cross-server moves, use GetMessage + AppendMessage instead.
- Avoid mixing IMailFolder implementations (local/maildir folders) with IMAP copies.
When it happens
Trigger: Calling folder.CopyTo(destination) or folder.MoveTo(destination) where destination was obtained from another ImapClient (e.g. two connections to different or even the same server), or a non-ImapFolder IMailFolder implementation (local mail folder, MemoryFolder).
Common situations: Migrating mail between accounts by opening two ImapClients and moving messages between them; mixing folder objects from UnitTests or a different provider; copying a folder reference captured before the client was reconnected/recreated (new Engine instance).
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- The uid is invalid.
- offset
- count
- The name is not a legal folder name.
- Cannot rename a folder using itself as the new parent…
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/5e2c950879c6cc15.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolder.cs:190
throw new FolderNotOpenException (FullName, access);
}
}
void CheckAllowIndexes ()
{
// Indexes ("Message Sequence Numbers" or MSNs in the RFCs) and * are not stable while MessageNew/MessageExpunge is registered for SELECTED and therefore should not be used
// https://tools.ietf.org/html/rfc5465#section-5.2
if (Engine.NotifySelectedNewExpunge)
throw new InvalidOperationException ("Indexes and '*' cannot be used while MessageNew/MessageExpunge is registered with NOTIFY for SELECTED.");
}
void CheckValidDestination (IMailFolder destination)
{
if (destination == null)
throw new ArgumentNullException (nameof (destination));
if (destination is not ImapFolder target || (target.Engine != Engine))
throw new ArgumentException ("The destination folder does not belong to this ImapClient.", nameof (destination));
}
internal void Reset ()
{
// basic state
((HashSet<string>) PermanentKeywords).Clear ();
((HashSet<string>) AcceptedKeywords).Clear ();
PermanentFlags = MessageFlags.None;
AcceptedFlags = MessageFlags.None;
Access = FolderAccess.None;
// annotate state
AnnotationAccess = AnnotationAccess.None;
AnnotationScopes = AnnotationScope.None;
MaxAnnotationSize = 0;
// condstore state
supportsModSeq = false;View on GitHub (pinned to 9d3859a785)