hashicorp/packer · error

Error uploading script: %s

Error message

Error uploading script: %s

What it means

Raised inside the retryable upload-and-run closure in Provision: after seeking the script file back to the start, comm.Upload pushes the script to the guest at p.config.RemotePath; if the communicator upload fails, the error is wrapped as "Error uploading script: %s". The retry.Config wrapper (StartRetryTimeout) re-runs the closure on failure, so this error surfaces only after retries are exhausted, meaning the guest communicator repeatedly refused or dropped the upload.

Source

Thrown at provisioner/windows-shell/provisioner.go:216

		}
		command, err := interpolate.Render(p.config.ExecuteCommand, &p.config.ctx)
		if err != nil {
			return fmt.Errorf("Error processing command: %s", err)
		}

		// Upload the file and run the command. Do this in the context of
		// a single retryable function so that we don't end up with
		// the case that the upload succeeded, a restart is initiated,
		// and then the command is executed but the file doesn't exist
		// any longer.
		var cmd *packersdk.RemoteCmd
		err = retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run(ctx, func(ctx context.Context) error {
			if _, err := f.Seek(0, 0); err != nil {
				return err
			}

			if err := comm.Upload(p.config.RemotePath, f, nil); err != nil {
				return fmt.Errorf("Error uploading script: %s", err)
			}

			cmd = &packersdk.RemoteCmd{Command: command}
			return cmd.RunWithUi(ctx, comm, ui)
		})
		if err != nil {
			return err
		}

		// Close the original file since we copied it
		f.Close()

		if err := p.config.ValidExitCode(cmd.ExitStatus()); err != nil {
			return err
		}
	}

	return nil

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Increase winrm_timeout / ssh timeouts and StartRetryTimeout so slow or intermittently flaky guest connections survive the retries.
  2. Verify the guest communicator is healthy at that point in the build (no restart in progress; ping/WinRM reachable) and fix any windows-restart/pause ordering.
  3. Check the guest's free disk space and that RemotePath's directory (usually a temp path) is writable.
  4. Inspect the wrapped error in the message for the concrete cause (e.g. 'unknown error post-upload', timeout, auth) and address accordingly.

Example fix

// before (HCL2): short WinRM timeout drops uploads
winrm_timeout = "10m"
// after
winrm_timeout = "1h"
winrm_use_ntlm = true  // if flaky negotiation was the cause
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: verify communicator reachability before provisioning phase
if err := testWinRm(host, user, pass, timeout); err != nil {
    return fmt.Errorf("guest unreachable before upload: %w", err)
}
// and ensure guest disk space via an earlier provisioner step

Try / catch

err := retry.Config{StartTimeout: 30 * time.Minute}.Run(ctx, func(ctx context.Context) error {
    if err := comm.Upload(remote, f, nil); err != nil {
        return fmt.Errorf("Error uploading script: %w", err) // retried
    }
    return nil
})
if err != nil { return fmt.Errorf("upload failed after retries: %w", err) }

Prevention

When it happens

Trigger: Within retry.Config{StartTimeout: p.config.StartRetryTimeout}.Run, f.Seek(0,0) succeeds but comm.Upload(p.config.RemotePath, f, nil) returns an error every attempt — unreachable guest, WinRM/SSH session drops mid-transfer, guest disk full, or remote path not writable. provisioner.go:210-219; the final wrapped error is returned after the retry timeout elapses.

Common situations: Windows guest rebooted or network blipped during provisioning so WinRM dropped; guest disk full preventing the temp upload; WinRM timeout too small for large scripts over slow links; communicator credentials/HTTPS misconfiguration; RemotePath colliding with an unwritable directory.

Related errors


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