hashicorp/packer · error
Only a script file or an inline script can be specified, not
Error message
Only a script file or an inline script can be specified, not both.
What it means
The PowerShell provisioner can execute a script file list or an inline script array, but not both, since they would use different execute_command strategies. Prepare rejects a block where scripts is non-empty and inline is also provided. The ambiguity is resolved by making the choice explicit in the template.
Source
Thrown at provisioner/powershell/provisioner.go:243
errs = packersdk.MultiErrorAppend(errs,
errors.New("Only one of script or scripts can be specified."))
}
if p.config.ElevatedUser == "" && p.config.ElevatedPassword != "" {
errs = packersdk.MultiErrorAppend(errs,
errors.New("Must supply an 'elevated_user' if 'elevated_password' provided"))
}
if p.config.Script != "" {
p.config.Scripts = []string{p.config.Script}
}
if len(p.config.Scripts) == 0 && p.config.Inline == nil {
errs = packersdk.MultiErrorAppend(errs,
errors.New("Either a script file or inline script must be specified."))
} else if len(p.config.Scripts) > 0 && p.config.Inline != nil {
errs = packersdk.MultiErrorAppend(errs,
errors.New("Only a script file or an inline script can be specified, not both."))
}
if p.config.ExecuteCommand == "" {
if p.config.Inline != nil && len(p.config.Scripts) == 0 {
p.config.ExecuteCommand = p.defaultExecuteCommand()
log.Printf("Using inline default execute command %s", p.config.ExecuteCommand)
} else {
p.config.ExecuteCommand = p.defaultScriptCommand()
log.Printf("Using script default execute command %s", p.config.ExecuteCommand)
}
}
if p.config.ElevatedExecuteCommand == "" {
if p.config.Inline != nil && len(p.config.Scripts) == 0 {
p.config.ElevatedExecuteCommand = p.defaultExecuteCommand()
log.Printf("Using inline default elevated execute command %s", p.config.ElevatedExecuteCommand)
} else {View on GitHub (pinned to eb36e3c3e4)
Solutions
- Remove the inline field and put the commands into the .ps1 file(s) referenced by scripts.
- Or remove script(s) and use only inline if no file-based script is needed.
- If both payloads are genuinely needed, split into two provisioner blocks — one file-based, one inline.
Example fix
// before
provisioner "powershell" {
scripts = ["./setup.ps1"]
inline = ["Write-Host done"]
}
// after
provisioner "powershell" {
scripts = ["./setup.ps1"]
}
provisioner "powershell" {
inline = ["Write-Host done"]
} Defensive patterns
Strategy: validation
Validate before calling
// Choose exactly one payload style:
assert {
condition = !(length(var.ps_scripts) > 0 && length(var.ps_inline) > 0)
error_message = "Use either scripts or inline in a powershell provisioner, not both."
} Prevention
- Keep file-based and inline payloads in separate provisioner blocks.
- When adding quick commands to an existing block, append them to the script file instead of adding inline.
- Run packer validate after template merges.
When it happens
Trigger: A powershell provisioner block setting both scripts (or script, which is folded into scripts) and inline, e.g. scripts = ["./a.ps1"] plus inline = ["dir"].
Common situations: Extending an existing file-based provisioner with a quick inline command instead of appending to the script; copy-paste merges of two provisioner blocks; conditional HCL where both branches contribute fields.
Related errors
- Only one of script or scripts can be specified.
- Must supply an 'elevated_user' if 'elevated_password' provid
- Either a script file or inline script must be specified.
- source must be specified when auto_generate is not enabled
- Only one of script or scripts can be specified.
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/8e56a1a6436683f2.
Report an issue: GitHub.