hashicorp/vagrant · error · VagrantPlugins::Salt::Errors::InvalidShasumError
The bootstrap-salt script downloaded from '%{source}' couldn
Error message
The bootstrap-salt script downloaded from '%{source}' couldn't be verified. Expected SHA256 '%{expected_sha}', but computed '%{computed_sha}' What it means
Raised by Vagrant's salt BootstrapDownloader when verifying the salt-bootstrap script: it downloads the script from the GitHub 'latest' release URL (bootstrap-salt.sh, or .ps1 for Windows guests), downloads the matching '.sha256' sidecar, extracts the last 64-char hex token via regex, computes SHA256 of the script, and raises InvalidShasumError with source/expected/computed on mismatch. Because the URL pins to 'latest' rather than a fixed release, any upstream republish, CDN skew between the script and its sidecar, or corrupted/proxied download makes verification fail.
Source
Thrown at plugins/provisioners/salt/bootstrap_downloader.rb:48
@logger.info "Downloaded and verified salt-bootstrap script"
script_file
end
def verify_sha256(script)
@logger.debug "Downloading sha256 file from #{source_url}#{SHA256_SUFFIX}"
sha256_file = download("#{source_url}#{SHA256_SUFFIX}")
sha256 = extract_sha256(sha256_file.read)
sha256_file.close
@logger.debug "Computing sha256 value from script file"
computed_sha256 = Digest::SHA256.hexdigest(script.read)
script.rewind
@logger.debug "Comparing sha256 values"
if computed_sha256 != sha256
@logger.debug "Mismatched sha256, expected #{sha256} but computed #{computed_sha256}"
raise Salt::Errors::InvalidShasumError, source: source_url, expected_sha: sha256, computed_sha: computed_sha256
end
@logger.debug "Sha256 values match"
end
def extract_sha256(text)
text.scan(/\b([a-f0-9]{64})\b/).last.first
end
def download(url)
URI(url).open
end
end
end
end
View on GitHub (pinned to 35f3160f4a)
Solutions
- Retry after a few minutes - the 'latest' release artifacts usually re-sync upstream
- Bypass caches: pull once on the host, verify `sha256sum bootstrap-salt.sh` against the sidecar manually, then set `salt.bootstrap_script_path` (or bootstrap_source) to that pinned local copy
- If behind a proxy, clear/refresh its cache for github.com/saltstack/salt-bootstrap or add an exception
- Report the mismatch to saltstack/salt-bootstrap if it persists - the release artifacts themselves are inconsistent
Example fix
# before (default: always chases 'latest', races .sha256 sidecar) config.vm.provision "salt" do |s| s.install_master = true end # after (pin a local, pre-verified script) # curl -LO https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh # curl -LO .../bootstrap-salt.sh.sha256 && sha256sum -c bootstrap-salt.sh.sha256 config.vm.provision "salt" do |s| s.install_master = true s.bootstrap_script_path = "vendor/bootstrap-salt.sh" end
Defensive patterns
Strategy: validation
Validate before calling
# Pin and verify the bootstrap script on the host before provisioning
require "digest"
require "open-uri"
script = URI.open("https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh")
expected = URI.open("https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh.sha256").read[/\b([a-f0-9]{64})\b/]
abort "sha mismatch" unless Digest::SHA256.hexdigest(script.read) == expected
File.binwrite("vendor/bootstrap-salt.sh", script.rewind && script.read)
config.vm.provision "salt" do |s|
s.bootstrap_script_path = "vendor/bootstrap-salt.sh"
end Type guard
def bootstrap_script_verified?(path, sha256_file)
expected = File.read(sha256_file)[/\b([a-f0-9]{64})\b/]
Digest::SHA256.hexdigest(File.read(path)) == expected
end Try / catch
begin env.cli(%w[provision]) rescue VagrantPlugins::Salt::Errors::InvalidShasumError => e # 'latest' release artifacts raced - clear caches and retry once sleep 120 retry end
Prevention
- Pin salt.bootstrap_script_path (or bootstrap_source) to a specific release instead of the default 'latest' URL
- Vendor and sha256-verify the bootstrap script in your repo so provisioning is hermetic
- Exclude github.com/saltstack/salt-bootstrap from caching proxies, or purge the cache when this error appears
When it happens
Trigger: Provisioning with the salt provisioner (default bootstrap_source) when the downloaded bootstrap-salt.sh digest does not equal the digest in bootstrap-salt.sh.sha256 - typically a race between artifact uploads on a fresh 'latest' release, a caching proxy serving mixed versions, or a truncated download.
Common situations: salt-bootstrap cutting a release minutes before you provision (script and .sha256 briefly inconsistent); corporate proxy/CDN caching one file from the old release and one from the new; MITM or AV stripping/modifying the shell script; Windows guests hitting the .ps1 variant of the same race.
Related errors
- This Vagrant environment has specified that it requires the
- The box '%{name}' could not be found or could not be accesse
- There was an error while downloading the metadata for this b
- Multiple URLs for a box can't be specified when adding versi
- The box you're adding has a name different from the name you
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/ec53abfd74679ec1.
Report an issue: GitHub.