So I have conclusions (partial, anyway):
CreatePhantom didn’t trigger any exception, so I don’t think the error originates from that.
The root cause of the issue remains NaN positions and/or orientations. The way it happened this time around was a lot more tricky though, hence why it took me so long to find it. The rotation quaternion the client sent back after jumping was all NaNs because the rotation matrix was slightly denormalized, causing the conversion to fail. However, the quaternion was “sanitized” somewhere along the chain and became all zeros, so it didn’t get caught by the SPObjUpdate patch I added (it checks for NaNs only), but a zero quaternion is still an invalid rotation matrix, so when converting it back it became full of NaNs again and would crash the server on some occasions.
I’ve tracked down and fixed the quaternion conversion (I can’t really help with rotation matrices becoming slightly denormalized, that’s just normal) on the client, but I’ve also added another check to SPObjUpdate in FLHook which requires the quaternion to be mostly normalized, so it’ll catch erroneous values like this in the future.