mbsync: near side box cannot be opened and far side box is not empty
2022-11-21
mbsync (project name isync) is a great tool to synchronise mails locally to your computer, and one that I wrote a blog post about recently. However, managing your emails manually means that occasionally you'll run into synchronisation issues. The issue at hand today is trying to delete a mail box that still contains mail, which for safety reasons mbsync tries to prevent.
Here's the setup: you delete mail box box_name
, while it still has mail inside it.
You use the --remove-far
option to propagate the deletion, but experience the following error:
$ mbsync --remove-far channel_name
C: 0/1 B: 9/11 F: +0/0 *0/0 #0/0 N: +0/0 *0/0 #0/0
Warning: channel channel_name: near side box box_name cannot be opened and far side box box_name is not empty.
C: 1/1 B: 11/11 F: +0/0 *0/0 #0/0 N: +0/0 *0/0 #0/0
This is because mbsync prevents deletion of non-empty mailboxes. See the man page:
man mbsync
...
Remove {None|Far|Near|Both}
Propagate mailbox deletions [to the far/near side].
...
Note that for safety, non-empty mailboxes are never deleted.
There isn't a way to override this behaviour. The process we therefore need to follow is, in brief:
- Re-create and fetch the missing mail box locally
- Delete the offending mail locally and resynchronise
- Delete the mailbox itself and resynchronise
Re-create and fetch the mail box locally
We firstly need to recreate the local mail box which is missing.
According to the maildir spec, this consists of one parent box_name
directory, with three children: cur
, new
, and tmp
.
$ cd ~/mail
$ mkdir box_name/cur box_name/new box_name/tmp
When you resynchronise, a new UIDVALIDITY will be created. This is a unique ID that identifies the mailbox between renamings. However, if the old UIDVALIDITY is still in the cache, mbsync will detect a change and error. For example:
$ mbsync -a
...
Maildir notice: no UIDVALIDITY, creating new.
Error: channel channel_name, near side box box_name: Unable to recover from UIDVALIDITY change.
C: 1/1 B: 11/11 F: +0/0 *0/0 #0/0 N: +0/0 *0/0 #0/0
So we can remove that box from the local cache:
$ mv ~/.mbsync/:remote_channel_name:Starred_:local_channel_name:Starred /tmp
And then fetch the mail locally:
$ mbsync -a
henleybeach:~$ mbsync -a
C: 3/3 B: 23/23 F: +0/0 *0/0 #0/0 N: +0/0 *0/0 #0/0
Delete the offending mail locally and resynchronise
Now we can delete/move the mail locally. You can do this in your mail client, or alternatively just by removing the contents of the mailbox yourself:
$ cd ~/mail
$ rm box_name/cur/* box_name/new/* box_name/tmp/*
Now we must re-synchronise, making sure to remove the emails on the far side with the Expunge option. This can be set in the config file, or overridden with the command line as follows:
$ mbsync -a --expunge-far
Delete the mailbox itself and resynchronise
Now the far side has dropped the mail, it's safe to remove the mailbox:
$ cd ~/mail
$ rmdir box_name/cur box_name/new box_name/tmp box_name
We resynchronise for a final time, removing the far box:
mbsync --remove-far -a