Consider a replica set with a primary and a secondary:
- The FCV is 6.0. An internal transaction (one with the new session id format) begins on the primary and passes this FCV check.
- The setFCV command starts and updates the target version in the FCV document to 5.0. The in-memory FCV is now "downgrading to 5.0".
- Right before the setFCV command starts aborting unprepared transactions, the internal transaction above enters the prepared state. So the internal transaction does not get aborted.
- The secondary applies the write to the FCV document and updates its in-memory FCV "downgrading to 5.0".
- The secondary applies the applyOps oplog entries for the prepared internal transaction but cannot to do so because of the the FCV check above so it hits this fassert.
The issue is that the secondary shouldn't check the FCV since the check has already been done by the primary.