Mandatory Constraints in Microsoft Project and Primavera P6

Here I review some impacts of “hard constraints” on the calculation of total float (or total slack) in logic-driven schedules. 

First a Note on Defining “Soft” and “Hard” Constraints

Some project scheduling guidance documents routinely categorize date constraints as either soft or hard depending on their ability to contradict or override network scheduling logic.  Mandatory date constraints — must-start-on (MSON) and must-finish-on (MFON) — are uniformly considered hard constraints because they can impose schedule dates that cause logic restraints to be violated.  As a result, the logic flow through the network is obstructed.  Early date constraints — start-no-earlier-than (SNET) and finish-no-earlier-than (FNET) — are uniformly considered considered soft constraints, presumably because they act in addition to, never in opposition to, the logic.

Both the DCMA 14-Point Assessment guidance (Nov’11) and the GAO Schedule Assessment Guide (Dec’15) also list late date constraints — start-no-later-than (SNLT) and finish-no-later-than (FNLT) — as hard constraints, even though they do NOT cause violations of logic restraints in most scheduling software.   The reason for this is unclear, though it may be related to the default “tasks will always honor their constraint dates” setting in Microsoft Project.  Under normal scheduling, this setting automatically converts a late date constraint to a mandatory constraint when it creates negative slack/float.  Another document (Planning and Scheduling Excellence Guide – PASEG v.3 – from the National Defense Industry Association) seems to recognize this issue, stating “Hard constraints do not allow the logic to drive the schedule (i.e. either restricts all movement or restricts movement to the right) on the constrained task.”  In this context, “restricts movement to the right” describes the impact of the setting on early dates (i.e. the default Start and Finish dates) in MSP.  Unfortunately, the DCMA 14-Point Assessment guidance continues to equate negative float with the existence of a hard constraint.  Such a position seems unsupported by any consistent set of base principles.

Microsoft Project

A recent discussion on technet raised the issue of slack/float calculation for tasks with hard constraints – in this case Project’s “Must Start On” (MSO) constraint.  A novice user of Microsoft Project (MSP), was puzzled by MSP’s calculation of non-zero total slack for an MSO-constrained task who’s early and late dates were the same.  That is, the expected definition of Total Slack as “Late Finish minus Early Finish” [*] was clearly NOT being followed.

*[The traditional CPM definition of Total Slack/Float is TS=LF-ES-Dur.  When Duration is a constant (as in MSP and P6) this simplifies to:

TS=(LF-Dur)-ES ==> TS=LS-ES, and

TS=LF-(ES+Dur) ==> TS=LF-EF.]

Consider the simple example comprising a three-task schedule with an MSO constraint on the second task and a deadline (a soft late constraint) on the third task, which I’ve shown below.

There are two basic issues about MSO (and MFO) constraints in Microsoft Project that come into play:

  1. Under typical default conditions, Project sets both the early start and late start equal to the MSO constraint date. This completely blocks logic flow through the task, and TS is zero.  I’ve illustrated this in the first chart below, where I’ve set a lenient MSO constraint on task t2 but imposed a deadline on the completion task t3 to create some negative slack.  Clearly the first task t1 should have negative slack, but the backward pass calculations don’t show it.
  2. If the early start imposed by the MSO constraint precedes the early start derived from the forward pass (i.e. the logic), then a logical conflict is created. If the “Tasks will always honor their constraint dates” box is checked in the Schedule options (the default condition), then Project keeps the imposed early and late starts – violating the CPM logic – and “resolves the conflict” by over-writing Total Slack with a negative value.  This case is presented in the middle chart below.  If the checkbox is not checked, then the Early Start is allowed to slip with the logic while the Late Start is retained.  I’ve shown this on the bottom chart.


The example presented is a “Mandatory Constraint,” which is strongly discouraged in general and is explicitly prohibited in many contexts.  Unchecking the “Tasks will always honor their constraint dates” box softens the impact of the constraint, but logic flow through the task is still interrupted.  Because of these issues, users of MSP would be well advised to avoid MSO or MFO constraints in any context where scheduling logic (and Total Slack) are important.

MSP/Primavera P6 Comparison

With the checkbox checked (i.e. default conditions), Microsoft’s “Must Start On” constraint seems to behave almost identically to P6’s “Mandatory Start” constraint.

  1. Like Project’s MSO, P6’s Mandatory Start constraint over-writes early AND late dates, thereby imposing a null Total Float and interrupting logic flow through the schedule.
  2. In the absence of a logical conflict, Mandatory Start (in P6) results in the same dates AND Total Float (null-value) as MSO in MSP.
  3. There is one minor difference. Whereas Project separately computes and imposes negative Total Slack (on the constrained task only) to highlight a logical conflict, P6 preserves the CPM-defined Total Float of zero on the constrained activity.  (This was the basis for the original question on technet.)  Both constraints impose negative slack/float on the predecessors of the constrained task/activity based on the logical conflict alone; negative slack/float from a more stringent constraint later in the project will be blocked.


With the checkbox un-checked, the resulting MSP schedule appears similar at first to P6’s schedule when using a (softer) constraint like “Start-On”.  This should not be misinterpreted.  As shown in the next chart, MSP continues to over-write the late date with the constraint date, even when the CPM-based late date is more restrictive.  Resulting predecessor slack values may be incorrect.  P6’s “Start On” constraint, on the other hand, results in a correct float calculation for the imposed conditions.