Imap synchronisation failure with READ-ONLY status

P.H. qikom at
Thu Aug 19 19:07:48 BST 2010


> [... "mailbox selected READ-ONLY" on ...]

I had the same problem and managed to write a quick and dirty patch that
seems to work for me.

Here is the original message I sent on the mailing list (no answers, I
still don't really understand what is going on) and the patch is attached...

If anyone can make sense out of that, I'd welcome any comment /


--------- 8< ----------------------------------------------------------

>From qikom at Fri Sep 11 02:17:15 2009
Date: Fri, 11 Sep 2009 02:17:15 +0200
From: "P.H." <qikom at>
To: offlineimap at
Subject: Possible fix for bug#142

Hello to all...

I finally decided to spend some time investigating bug #142, since I've
been suffering from it for some time.
 ( )

Summary: propagating changes to an account on the Zimbra server of some
French Internet provider (Free) crashes offlineimap with

Thread 'Folder sync Com[Junk]' terminated with exception:
  File "/usr/lib/pymodules/python2.5/offlineimap/folder/", line 377, in processmessagesflags
    assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
AssertionError: Error with store: mailbox selected READ-ONLY

Note: I am using offlineimap_6.2.0

Modifying line 126 of (in function "cachemessagelist")
-  , readonly = 1, force = 1)
+            self.selectro(imapobj)
it seems to correct the problem.

If I only remove the 'readonly' flag, it fails for the special folders
'Contacts', 'Emailed Contacts' and 'Chats' which are probably not real
imap folders. (Not a huge problem for me since I filter them in my

So, in file offlineimap/folders/, is there a reason for using
"selectro" in "getuidvalidity" but not in "cachemessagelist". (nor in
"quickchanged" or "getmessage").

Right now, "selectro" is only used once, so it might be a good thing to
add an optional argument 'force' and use this function whenever
possible.  Pretending that I know what I am doing (I don't), I attach a
tiny patch doing that...
Hopefully, someone more knowledgeable can improve it.

Now, that might or might not fix bug #142, but I'd still like to
understand what is going on.

My first guess is that there is some problem with the Zimbra software.
(This account used to work before the provider switched to using

My other guess is that this also has something to do with threads...  I
can connect to the account and issue commands using imaplib.IMAP4, or

More probably, a little bit of both.

Since I am not familiar with threads programming and I don't know how to
debug them, I am in a dead end.

Does anybody have an idea?
Could it be that some 'readonly' flag leaks from one thread (typically
from the one calling "cachemessagelist") to another?

Another very strange things which I encountered trying to fix this is
the following: replacing the call to "selectro" in function
"getuidvalidity" by, readonly = 1)
I could, "sometimes", propagate changes. I seemed that I had to wait
about 1 minute between calls to offlineimap.
(In the meantime, I could still issue commands via a simple imaplib
I am confused...

Thanks in advance!

--------- 8< ----------------------------------------------------------

I don't quite hear what you say, but I beg to differ
entirely with you.
    -- Augustus De Morgan
-------------- next part --------------
--- offlineimap-orig/offlineimap/folder/	2009-08-12 22:25:27.000000000 +0200
+++ offlineimap-work/offlineimap/folder/	2009-09-11 02:11:17.000000000 +0200
@@ -41,15 +41,15 @@
         self.randomgenerator = random.Random()
-    def selectro(self, imapobj):
+    def selectro(self, imapobj, force = None):
         """Select this folder when we do not need write access.
         Prefer SELECT to EXAMINE if we can, since some servers
         (Courier) do not stabilize UID validity until the folder is
+  , force = force)
         except imapobj.readonly:
-  , readonly = 1)
+  , readonly = 1, force = force)
     def getaccountname(self):
         return self.accountname
@@ -82,7 +82,7 @@
         imapobj = self.imapserver.acquireconnection()
             # Primes untagged_responses
-  , readonly = 1, force = 1)
+            self.selectro(imapobj, force = 1)
                 # Some mail servers do not return an EXISTS response if
                 # the folder is empty.
@@ -122,7 +122,7 @@
             # Primes untagged_responses
-  , readonly = 1, force = 1)
+            self.selectro(imapobj, force = 1)
                 # Some mail servers do not return an EXISTS response if
                 # the folder is empty.
@@ -160,7 +160,7 @@
         ui = UIBase.getglobalui()
         imapobj = self.imapserver.acquireconnection()
-  , readonly = 1)
+            self.selectro(imapobj)
             initialresult = imapobj.uid('fetch', '%d' % uid, '(BODY.PEEK[])')
             ui.debug('imap', 'Returned object from fetching %d: %s' % \
                      (uid, str(initialresult)))

More information about the OfflineIMAP-project mailing list