Skip to content

Windows ESP: gate awaiting_configuration=None on user-scope ServerHasFinishedProvisioning 200 ack #49252

Description

@lukeheath

Problem

Follow-up hardening from #49134 / #49250.

The immediate fix for the Windows ESP "Account setup" hang (#49250) guarantees the user-scope DMClient node exists before the release-phase Replace ./User/.../FirstSyncStatus/ServerHasFinishedProvisioning is sent, so the write no longer 405s.

However, Fleet still commits awaiting_configuration = None (the compare-and-swap in handleESPRelease) before it knows whether the device acked that user-scope Replace with a 200. The release commands are sent inline in the same management session, and persistESPFinalCommands backs them up so the command-retry infrastructure resends them if the whole response is dropped. But if the user-scope Replace specifically fails on-device for any other reason (not a dropped response), Fleet has already declared the ESP finished on its side while the device is still stuck on "Account setup."

As @getvictor noted on #49134:

I agree that Fleet must not consider the ESP finished until the user-scope ServerHasFinishedProvisioning Replace has acked 200 (or the existing timeout/block paths fire).

What good looks like

  • Fleet does not transition awaiting_configuration out of Active (to None) until the user-scope ServerHasFinishedProvisioning Replace has been acked 200 by the device — OR one of the existing terminal paths (3-hour timeout, hard/soft block) fires.
  • On a non-200 ack of the user-scope release Replace, Fleet re-attempts the finalize (re-Add + re-Replace) on the next management session rather than treating the device as released.
  • Existing behavior for the timeout and block paths is unchanged.

Notes / investigation

  • The current finalize commits the CAS Active -> None right after persisting the commands, before any ack is observed. Gating on the ack means tracking the specific user-scope Replace command's result before allowing the CAS, which is a change to the finalize state machine (handleESPRelease in server/service/microsoft_mdm.go).
  • @getvictor also flagged worth investigating: whether the original hold-phase Add ./User/.../DMClient/Provider/Fleet can fail (rather than 418) when no interactive user session exists yet during the Device-setup phase, and whether Windows later creates that node via a different mechanism. Worth confirming on a real OOBE device.
  • Not a release blocker on its own: Fix intermittent Windows ESP Account setup hang (user-scope 405 race) #49250 resolves the reported P1 hang. This is defense-in-depth so a future/unrelated user-scope failure can't silently strand a device.

Related: #49134, #49250

Metadata

Metadata

Assignees

No one assigned

    Labels

    #g-power-to-pcPower to the PC working groupstoryA user story defining an entire feature~engineering-initiatedEngineering-initiated story, such as a bug, refactor, or contributor experience improvement.~windowsAn issue related to Windows hosts.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions