hashicorp/packer · error
Error opening shell script: %s
Error message
Error opening shell script: %s
What it means
Provision iterates over the resolved script paths (inline-generated temp scripts plus configured script files) and opens each locally to upload it (provisioner/shell/provisioner.go:302). This error means os.Open(path) on a script file failed — the file does not exist at that path, is unreadable, or the path is a directory. For temp inline scripts this indicates the temp file was removed early; for user scripts it is almost always a bad path in the template.
Source
Thrown at provisioner/shell/provisioner.go:302
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)
if err != nil {
return fmt.Errorf("Error opening shell script: %s", err)
}
defer f.Close()
// Compile the command
// These are extra variables that will be made available for interpolation.
generatedData["Vars"] = flattenedEnvVars
generatedData["EnvVarFile"] = p.config.envVarFile
generatedData["Path"] = p.config.RemotePath
p.config.ctx.Data = generatedData
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,View on GitHub (pinned to eb36e3c3e4)
Solutions
- Verify each path in scripts exists relative to where packer is invoked (ls -l <path>).
- Use absolute paths or correct the working directory in CI before running packer.
- Ensure script files are committed/copied into the CI workspace.
- Fix file permissions (chmod +r) or replace broken symlinks.
- On case-sensitive filesystems, match the filename case exactly.
Example fix
// before
provisioner "shell" {
scripts = ["./scripts/setup.sh"]
}
// after — path verified from the template's directory
provisioner "shell" {
scripts = ["${path.root}/scripts/setup.sh"]
} Defensive patterns
Strategy: validation
Validate before calling
// validate all script paths before invoking packer
for f in scripts/setup.sh scripts/bootstrap.sh; do
[ -f "$f" ] && [ -r "$f" ] || { echo "missing/unreadable script: $f"; exit 1; }
done
packer build template.pkr.hcl Try / catch
// if invoking provisioner programmatically
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("script %q not found; check scripts[] paths relative to cwd", path)
}
return err
} Prevention
- Reference scripts with ${path.root}/ so paths resolve relative to the template.
- Commit all referenced scripts to the repo and verify CI checkouts include them.
- Run packer from the directory you expect; log pwd in CI before building.
- Check for broken symlinks and case mismatches on case-sensitive filesystems.
When it happens
Trigger: script or scripts entries point to files that don't exist relative to the packer run directory; the file exists on the machine where the template was edited but not where packer runs (CI checkout mismatch); a symlink target is missing; permissions deny read.
Common situations: Wrong relative path in the shell provisioner's scripts list; running packer from a different working directory than expected in CI; files not checked into the repo; Windows path separators vs Unix; case-sensitivity mismatch on Linux.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Only one of script or scripts can be specified.
- Either a script file or inline script must be specified.
- Only a script file or an inline script can be specified, not
- Bad script '%s': %s
- Error stating powershell script: %s
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/ff33e4b67fb7db66.
Report an issue: GitHub.