 Since it is rebuilding the registry on every restart anyway, I went ahead and made the changes to my OFS/Application.py. I confirmed that ZGlobals is now an OOBTree, but subsequent restarts continue to show the same problem :-( I've placed pdb.set_trace all over the DB state-loading code. When I attempt to step into the state = unpickler.load() line during the loading of the ZGlobals OOBTree, it immediately throws an ImportError on the ZClass GUID. It doesn't even seem to enter the persistent_load or classLoader methods. Shot in the dark #0: Does it enter the ClassFactory function in Zope.ClassFactory? That's part of the ZClass magic... although there are two ways that the pickler tries to load classes. ZODB only tries to load Persistent instances as ZClasses. If there are things inside the pickles that are not Persistent, yet come from a ZClass, ZODB will not treat them kindly. Shot in the dark #0: Unfortunately, there's one bit of ZODB that I still don't fully understand, and that's setklassstate(). You might be running into this somehow. I'd hazard a guess that the latest cPickleCache does not do the right thing with setklassstate(), since no one has committed to maintain that part. Ugh, we need unit tests for that. Tracing this has gotten me all confused. I understand (I think) that when a ZClass instance is unpickled, persistent_load gets the ZClass GUID and uses that to look up the actual _zclass_ class in ZGlobals. What I can't understand is why it would try to import the GUID when loading ZGlobals. All it has it in is strings and the _zclass_ ExtensionClasses, and they should be handled by the normal unpickling machinery, right? 