Message Recovery

During initialization, or in the middle of a FIX session, message gaps may occur which are detected via the tracking of incoming sequence numbers. The following section provides details on how to recover messages.

As previously stated, each FIX participant must maintain two sequence numbers for each FIX session, one each for incoming and outgoing messages which are initialized at ‘1’ at the beginning of the FIX session. Each message is assigned a unique (by connection) sequence number, which is incremented after each message. Likewise, every message received has a unique sequence number and the incoming sequence counter is incremented after each message.

When the incoming sequence number does not match the expected number corrective processing is required. Note that the SeqReset-Reset message (used only to recover from a disaster scenario vs. normal resend request processing) is an exception to this rule as it should be processed without regards to its MsgSeqNum(34). If the incoming message has a sequence number less than expected and the PossDupFlag(43) is not set, it indicates a serious error. It is strongly recommended that the session be terminated and manual intervention be initiated. If the incoming sequence number is greater than expected, it indicates that messages were missed and retransmission of the messages is requested via the Resend Request<2> (see the earlier section, Ordered Message Processing).

Note: For the purposes of the following paragraphs requester refers to the party requesting the resend and resender refers to the party responding to the request. The process of resending and synchronizing messages is referred as “gap filling”.

Upon receipt of a Resend Request<2>, the resender can respond in one of three ways:

  1. retransmit the requested messages (in order) with the original sequence numbers and PossDupFlag(43) set to “Y” except for the administrative messages (listed below) which are not to be resent and which require a SeqReset-GapFill<4> (see #2)
  2. issue a SeqReset-GapFill<4> with PossDupFlag(43) set to “Y” message to replace the retransmission of administrative and application messages
  3. issue a SeqReset-Reset<4> with PossDupFlag(43) set to “Y” to force sequence number synchronization

The normal course of action involves a combination of #1 and #2. Note that #3 should be used ONLY to recover from a disaster situation which cannot be otherwise recovered via “Gap Fill” mode.

During the gap fill process, certain administrative messages should not be retransmitted. Instead, a special SeqReset-GapFill<4> message is generated. The administrative messages which are not to be resent are: Logon<A>, Logout<5>, ResendRequest<2>, Heartbeat<0>, TestRequest<1> and SeqReset-Reset<4> and SeqReset-GapFill<4>. The SeqReset-GapFill<4> can also be used to skip application messages that the sender chooses not to retransmit (e.g. aged orders). This leaves Reject<3> as the only administrative message which can be resent.

All FIX implementations must monitor incoming messages to detect inadvertently retransmitted administrative messages (PossDupFlag(43) flag set indicating a resend). When received, these messages should be processed for sequence number integrity only; the business/application processing of these message should be skipped (i.e. do not initiate gap fill processing based on a resent ResendRequest<2>).

If there are consecutive administrative messages to be resent, it is suggested that only one SeqReset-GapFill<4> message be sent in their place. The sequence number of the SeqReset-GapFill<4> message is the next expected outbound sequence number. The NewSeqNo(36) field of the GapFill<4> message contains the sequence number of the highest administrative message in this group plus 1. For example, during a Resend operation there are 7 sequential administrative messages waiting to be resent. They start with sequence number 9 and end with sequence number 15. Instead of transmitting 7 Gap Fill<4> messages (which is perfectly legal, but not network friendly), a SeqReset-GapFill<4> message may be sent. The sequence number of the Gap Fill<4> message is set to 9 because the remote side is expecting that as the next sequence number. The NewSeqNo(36) field of the GapFill<4> message contains the number 16, because that will be the sequence number of the next message to be transmitted.

Sequence number checking is a vital part of FIX session management. However, a discrepancy in the sequence number stream is handled differently for certain classes of FIX messages. The table below lists the actions to be taken when the incoming sequence number is greater than the expected incoming sequence number.

NOTE: In *ALL* cases except the Sequence Reset - Reset<4> message, the FIX session should be terminated if the incoming sequence number is less than expected and the PossDupFlag(43) is not set. A Logout<5> message with some descriptive text should be sent to the other side before closing the session.

Response by message type:

Message type Action to be taken on Sequence # mismatch
Logon<A> Must always be the first message transmitted. Authenticate and accept the connection. After sending a Logon<A> confirmation back, send a ResendRequest<2> if a message gap was detected in the Logon<A> sequence number.
Logout<5>

If a message gap was detected, issue a ResendRequest<2> to retrieve all missing messages followed by a Logout<5> message which serves as a confirmation of the logout request. DO NOT terminate the session. The initiator of the Logout sequence has responsibility to terminate the session. This allows the Logout<5> initiator to respond to any ResendRequest<2> message.

If this side was the initiator of the Logout sequence, then this is a Logout<5> confirmation and the session should be immediately terminated upon receipt.

The only exception to the “do not terminate the session” rule is for an invalid Logon<A> attempt. The session acceptor has the right to send a Logout message and terminate the session immediately. This minimizes the threat of unauthorized connection attempts.

ResendRequest<2>

Perform the Resend processing first, followed by a ResendRequest<2> of your own in order to fill the incoming message gap.

SeqReset-GapFill<4>

Send a ResendRequest<2> back. Gap Fill messages behave similar to a SeqReset message. However, it is important to insure that no messages have been inadvertently skipped over. This means that GapFill messages must be received in sequence. An out of sequence GapFill is an abnormal condition

SeqReset-Reset<4>

Ignore the incoming sequence number. The NewSeqNo(36) field of the SeqReset message will contain the sequence number of the next message to be transmitted.

All Other Messages

Perform Gap Fill operations.