Home  |  software  |  Musings  |  Pictorial  |  Academics  |  Links


Rescuing Mail.app Orphaned Emails

So for absolutely no good reason, I just selected my main inbox in Mail.app, went up to the Mailbox menu and chose to Rebuild the mailbox. And boom, everything after January of 2006 disappeared. Not very nice, Mail.app!

Here's how I got my emails back. This is seriously not for faint of heart. Seriously. And any arbitrary update to either the operating system or to Mail.app might break my instructions. And it's a pain in the ass. And this is only for POP email, no clue how things work with IMAP. And you need to have Apple's free Developer Tools installed. And these instructions are only for Intel machines. And your problem is probably something different anyway.

Still here? Okay, let's rock. Quit Mail if it's running. Back up the folder at <your home directory>/Library/Mail! I'm not joking, back it up!

First, all of your email is actually stored in various folders in <your home directory>/Library/Mail. If you dig around in there, you'll find each of your mailboxes as a folder with a "mbox" extension, and each of those will contain a "Messages" folder. But if the problem that affected me has also bitten you, there may also be folders named "Messages-gobbledygook". Move the contents of those into the "Messages" folder and throw them away. Also, in the root folder, you'll see files with names like "Envelope Index". Toss 'em. You did make a backup of this whole mess, right?

It's possible that you'll have to launch Mail multiple times to fix everything. If so, every time you quit, you'll have to repeat the above steps.

Okay, on to the real action. The problem for me was that I had about 10 corrupted email messages scattered throughout my various inboxes. During the Rebuild process, Mail tried to read them, failed, logged the error out to the Console, but then just bailed on the rebuild process instead of moving on to the next message as it should have done. So our goal is to find these problematic messages and get rid of them.

In /Applications/Utilities/Terminal, type:

cd /Applications/Mail.app/Contents/MacOS
gdb ./Mail

The gdb debugger should launch. If it doesn't, you don't have the developer tools installed, bye-bye! Still here? Then type:

source /usr/libexec/gdb/plugins/MacsBug/gdbinit-MacsBug-without-plugin
br NSLog

You have told gdb that we're going to be doing assembly language level debugging. You have set a breakpoint on the NSLog command, which is the command that logs the error message to the Console. Then, you have launched Mail.app. Accordingly, you should now see it launch, but since you deleted the "Envelope Index" files, it will welcome you to Tiger and ask you if you'd like to import your mailboxes. You do indeed wish to do so.

As the import process is proceeding, keep an eye on the Terminal. If you see it drop back to a command line prompt, you've found one of the bad messages. It'll look something like this:

Breakpoint 1, 0x9284b304 in NSLog ()

At this point, type "so" and hit return. This will step over assembly language instructions one at a time. Do this six times. After the sixth time, a log message will have been printed out. Mine looks something like this:

2007-10-10 02:01:35.823 Mail[499] couldn't load body for <RecoveredMessage: 0x16b83420>, aborting
0x9284b319 in NSLog ()
Dump of assembler code from 0x9284b319 to 0x9284b321:
0x9284b319 <NSLog+27>: leave
0x9284b31a <NSLog+28>: ret
0x9284b31b <NSLog+29>: nop
0x9284b31c <NSLog+30>: nop

The important thing is the bit of gook that comes after the text "RecoveredMessage". In the case above, it is "0x16b83420". We're going to use that to find out where in the filesystem the problematic message is. Type (substituting in the appropriate text, of course):

po *(int *) (0x16b83420 + 60)

and gdb will spit out the filesytem path to the message that caused the problem. Copy-paste it somewhere where you can find it later.

Type "c" to continue running mail, and keep on doing this until Mail has finished importing your messages. It's possible that you might also see the message:

2007-10-10 02:05:47.750 Mail[499] failed to get body for message <LibraryMessage: 0x16bd2de0, library id: 13493>

In this case, you can get the path using (again, substitute the appropriate text):

po [0x16bd2de0 path]

Okay, at this point Mail should be up and running, and your messages should still be missing. Quit Mail and go delete the "Envelope Index" file(s) again, and go fix the "Messages-gobbledygook" folders again as I described at the very beginning of this article. Then, throw away all of the "emlx" files that you noted earlier as being problematic.

That's it! Run Mail again by typing "r" and repeat until Mail imports all of the messages without ever dropping into gdb. At that point, everything should be groovy and your messages should have magically reappeared!


© 2005 — All Rights Reserved Site credits >