As per my knowledge in simpler terms, it happens when a transaction uses the spool of another transaction(for which spool is assigned), reason may be some internal malfunctions as stated. In that scenario the transaction attempting to use the left over spool of ongoing transaction is aborted.
Here even I want to know how spool is allocated transaction wise?
Left-over spool is always a bug. And the problem is seldom (never?) with the query that gets the 2667 error; as the name implies, some prior transaction did not properly clean up its spool usage.
Short of applying the latest maintenance level (or upgrading database release), there's not much you can do unless you can somehow identify what "unusual" situation is triggering the bug - and avoiding that.
One other thought: A database restart removes ALL spool files - so there is a chance that forcing a restart could make encountering "left-over" spool less frequent. It won't actually fix anything, and would help only if the root cause of the left-over spool is something that has happened many times since last restart, but seldom happens now.