hashicorp/packer · error
Bad source '%s': %s
Error message
Bad source '%s': %s
What it means
During Prepare of the file provisioner (direction=upload), each configured source is stat'ed on the host. When generated=false (the default, expressed here as == false) and os.Stat fails — usually the file does not exist — this error is appended to the validation errors. The %s carries the underlying OS error (e.g. 'no such file or directory').
Source
Thrown at provisioner/file/provisioner.go:111
if p.config.Direction == "" {
p.config.Direction = "upload"
}
var errs *packersdk.MultiError
if p.config.Direction != "download" && p.config.Direction != "upload" {
errs = packersdk.MultiErrorAppend(errs,
errors.New("Direction must be one of: download, upload."))
}
if p.config.Source != "" {
p.config.Sources = append(p.config.Sources, p.config.Source)
}
if p.config.Direction == "upload" {
for _, src := range p.config.Sources {
if _, err := os.Stat(src); p.config.Generated == false && err != nil {
errs = packersdk.MultiErrorAppend(errs,
fmt.Errorf("Bad source '%s': %s", src, err))
}
}
}
if len(p.config.Sources) > 0 && p.config.Content != "" {
errs = packersdk.MultiErrorAppend(errs,
errors.New("source(s) conflicts with content."))
}
if p.config.Destination == "" {
errs = packersdk.MultiErrorAppend(errs,
errors.New("Destination must be specified."))
}
if errs != nil && len(errs.Errors) > 0 {
return errs
}
View on GitHub (pinned to eb36e3c3e4)
Solutions
- Create the source file or fix the path before running packer
- Set generated = true if the file is produced at runtime by generated data / a prior provisioner so the stat check is skipped
- Use an absolute path or correct the relative path relative to the template's directory
- Switch direction to download if you actually meant to fetch a file from the machine
Example fix
// before
provisioner file {
source = "app.tar.gz"
destination = "/tmp/app.tar.gz"
}
// after
provisioner file {
source = "app.tar.gz"
destination = "/tmp/app.tar.gz"
generated = true
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate upload sources in shell before packer build:
for f in $SOURCES; do test -e "$f" || echo "missing: $f"; done
// In Go config validation:
for _, src := range cfg.Sources {
if _, err := os.Stat(src); err != nil && !cfg.Generated {
fmt.Printf("source will fail validation: %s (%v)\n", src, err)
}
} Prevention
- Run packer validate before build — this error is caught at Prepare time
- Set generated = true for files created at build time rather than pre-existing on disk
- Use absolute paths anchored to the template directory
- Verify direction: stat checks only apply to upload
When it happens
Trigger: file provisioner with direction "upload" (the default), a source path that does not exist on the build host at template-validation time, and generated not set to true.
Common situations: Typo in the source path; the file is produced later by a previous provisioner or build step but `generated` was not set; relative path resolved from a different working directory; path valid on the remote but being used for upload.
Related errors
- The `bucket_name` must be specified
- `channel` is currently a required field.
- the `bucket_name` must be specified
- the `channel_name` must be specified
- the `url` must be specified
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/e4c1c29c36e882a3.
Report an issue: GitHub.