hashicorp/packer · error

Communicator wait canceled

Error message

Communicator wait canceled

What it means

This error is returned by waitForCommunicator in the windows-restart provisioner when the context passed into the retry loop is canceled or times out. The provisioner polls the Windows guest with a restart-check command until the machine has rebooted and the communicator reconnects; if the wait context ends first (build timeout, interrupt, or cancellation), the loop exits with this error. It signals that Packer gave up waiting for the VM to come back rather than that the restart itself failed.

Source

Thrown at provisioner/windows-restart/provisioner.go:228

}

var waitForCommunicator = func(ctx context.Context, p *Provisioner) error {
	runCustomRestartCheck := true
	if p.config.RestartCheckCommand == DefaultRestartCheckCommand {
		runCustomRestartCheck = false
	}
	// This command is configurable by the user to make sure that the
	// vm has met their necessary criteria for having restarted. If the
	// user doesn't set a special restart command, we just run the
	// default as cmdModuleLoad below.
	cmdRestartCheck := &packersdk.RemoteCmd{Command: p.config.RestartCheckCommand}
	log.Printf("Checking that communicator is connected with: '%s'",
		cmdRestartCheck.Command)
	for {
		select {
		case <-ctx.Done():
			log.Println("Communicator wait canceled, exiting loop")
			return fmt.Errorf("Communicator wait canceled")
		case <-time.After(retryableSleep):
		}
		if runCustomRestartCheck {
			// run user-configured restart check
			err := cmdRestartCheck.RunWithUi(ctx, p.comm, p.ui)
			if err != nil {
				log.Printf("Communication connection err: %s", err)
				continue
			}
			log.Printf("Connected to machine")
			runCustomRestartCheck = false
		}
		// This is the non-user-configurable check that powershell
		// modules have loaded.

		// If we catch the restart in just the right place, we will be able
		// to run the restart check but the output will be an error message
		// about how it needs powershell modules to load, and we will start

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Increase the build/provisioner timeout (e.g. Packer 'pause_before'/'timeout' or the build timeout setting) so slow Windows reboots fit inside the wait window.
  2. Verify the guest actually reboots and reconnects: fix communicator (winrm/ssh) settings, network, and credentials so the restart check succeeds quickly.
  3. Set restart_check_command to a command appropriate for your image so readiness is detected as soon as the machine is truly up.
  4. If this appears on every run with no timeout, check for an interrupted run or an upstream context cancellation (Ctrl-C) rather than a guest-side problem.

Example fix

// template before: reboot exceeds default timeout
{
  "type": "windows-restart"
}
// after: allow a longer wait and a targeted check
{
  "type": "windows-restart",
  "restart_check_command": "powershell -command \"& {sleep 5}\"",
  "pause_before": "2m"
}
// and/or raise the build timeout: "packer build -timeout=2h windows.pkr.hcl"
Defensive patterns

Strategy: retry

Validate before calling

// in HCL2 template, ensure generous timeout before build
// packer build -timeout=3h windows.pkr.hcl
// and confirm restart_check_command is reachable:
// packer validate windows.pkr.hcl

Try / catch

// Packer surfaces this as a provisioner failure; wrap CLI runs to detect it
out, err := exec.Command("packer", "build", tpl).CombinedOutput()
if err != nil && strings.Contains(string(out), "Communicator wait canceled") {
    log.Println("restart wait exceeded timeout; re-run with a larger -timeout")
}

Prevention

When it happens

Trigger: Context passed to waitForCommunicator is done (ctx.Done() fires) while the loop is polling: the build's timeout expired before the Windows guest finished rebooting, the user pressed Ctrl-C, or an ancestor context (e.g. the build's retry/timeout wrapper around the restart wait) was canceled. Any Windows-builder template using the windows-restart provisioner where the reboot takes longer than the allowed wait hits this at provisioner.go:226-228.

Common situations: Slow Windows updates rebooting far longer than the default wait/timeout; heavily loaded CI runners or nested virtualization making boot take minutes; a restart_check_command that never succeeds so the loop never exits before the context deadline; network/communicator misconfiguration meaning the VM never becomes reachable so the poll times out.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/e024b45830dcd04b. Report an issue: GitHub.