hashicorp/packer · error

Error chmodding script file to 0600 in remote machine: %s

Error message

Error chmodding script file to 0600 in remote machine: %s

What it means

Right after uploading the env-var file, Packer runs `chmod 0600 <remoteVFName>` on the remote machine through the communicator (provisioner/shell/provisioner.go:282). This error wraps a failure to start that remote command — i.e., the communicator session could not be established or the command could not be launched. Note cmd.Wait() is called but the chmod exit status is not checked; only the Start failure is reported here.

Source

Thrown at provisioner/shell/provisioner.go:282

				return err
			}

			var r io.Reader = tf
			if !p.config.Binary {
				r = &UnixReader{Reader: r}
			}
			remoteVFName := fmt.Sprintf("%s/%s", p.config.RemoteFolder,
				fmt.Sprintf("varfile_%d.sh", rand.Intn(9999)))
			if err := comm.Upload(remoteVFName, r, nil); err != nil {
				return fmt.Errorf("Error uploading envVarFile: %s", err)
			}
			tf.Close()

			cmd = &packersdk.RemoteCmd{
				Command: fmt.Sprintf("chmod 0600 %s", remoteVFName),
			}
			if err := comm.Start(ctx, cmd); err != nil {
				return fmt.Errorf("Error chmodding script file to 0600 in remote machine: %s", err)
			}
			cmd.Wait()
			p.config.envVarFile = remoteVFName
			return nil
		})
		if err != nil {
			return err
		}
	}

	// Create environment variables to set before executing the command
	flattenedEnvVars := p.createFlattenedEnvVars()

	for _, path := range scripts {
		ui.Say(fmt.Sprintf("Provisioning with shell script: %s", path))

		log.Printf("Opening %s for reading", path)
		f, err := os.Open(path)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Raise ssh MaxSessions/handshake limits (ssh_keep_alive_interval, ssh_handshake_attempts) or disable connection pooling.
  2. Increase start_retry_timeout so retries ride out reconnection windows.
  3. Ensure no restart provisioner reboots the machine without waiting for SSH to come back.
  4. Check the remote host's sshd logs (auth.log) for session refusal causes such as fail2ban.
  5. Run with PACKER_LOG=1 to capture the exact communicator Start error.

Example fix

// before
source "amazon-ebs" "ex" {
  ssh_handshake_attempts = 10
}
// after
source "amazon-ebs" "ex" {
  ssh_handshake_attempts     = 30
  ssh_keep_alive_interval    = "30s"
}
Defensive patterns

Strategy: retry

Validate before calling

// confirm sshd tolerates the session load before building
ssh -o ConnectTimeout=5 "$SSH_USER@$SSH_HOST" 'echo remote-ok' || { echo "ssh session start failed"; exit 1; }

Try / catch

// communicate-level: treat Start failures as transient and retry with backoff
err := retry.Config{StartTimeout: 10 * time.Minute}.Run(ctx, func(ctx context.Context) error {
    if err := p.Provision(ctx, ui, comm, data); err != nil {
        if strings.Contains(err.Error(), "chmodding script file") {
            return err // retried by retry.Run
        }
        return retry.Fatal(err)
    }
    return nil
})

Prevention

When it happens

Trigger: comm.Start(ctx, cmd) fails immediately after a successful upload: SSH connection dropped between upload and chmod, session multiplexing exhausted (MaxSessions), or the shell on the remote host cannot be spawned.

Common situations: OpenSSH MaxSessions limit reached with connection pooling; remote machine rebooted mid-provision by a restart provisioner; sshd rate limiting or fail2ban blocking repeated connections; flaky cloud networking.

Related errors


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