{"record":{"id":"ec53abfd74679ec1","repo":"hashicorp/vagrant","slug":"the-bootstrap-salt-script-downloaded-from-sourc","errorCode":null,"errorMessage":"The bootstrap-salt script downloaded from '%{source}' couldn't be verified. Expected SHA256 '%{expected_sha}', but computed '%{computed_sha}'","messagePattern":"The bootstrap-salt script downloaded from '%(.+?)' couldn't be verified\\. Expected SHA256 '%(.+?)', but computed '%(.+?)'","errorType":"exception","errorClass":"VagrantPlugins::Salt::Errors::InvalidShasumError","httpStatus":null,"severity":"error","filePath":"plugins/provisioners/salt/bootstrap_downloader.rb","lineNumber":48,"sourceCode":"\n        @logger.info \"Downloaded and verified salt-bootstrap script\"\n        script_file\n      end\n\n      def verify_sha256(script)\n        @logger.debug \"Downloading sha256 file from #{source_url}#{SHA256_SUFFIX}\"\n        sha256_file = download(\"#{source_url}#{SHA256_SUFFIX}\")\n        sha256 = extract_sha256(sha256_file.read)\n        sha256_file.close\n\n        @logger.debug \"Computing sha256 value from script file\"\n        computed_sha256 = Digest::SHA256.hexdigest(script.read)\n        script.rewind\n\n        @logger.debug \"Comparing sha256 values\"\n        if computed_sha256 != sha256\n          @logger.debug \"Mismatched sha256, expected #{sha256} but computed #{computed_sha256}\"\n          raise Salt::Errors::InvalidShasumError, source: source_url, expected_sha: sha256, computed_sha: computed_sha256\n        end\n        @logger.debug \"Sha256 values match\"\n      end\n\n      def extract_sha256(text)\n        text.scan(/\\b([a-f0-9]{64})\\b/).last.first\n      end\n\n      def download(url)\n        URI(url).open\n      end\n    end\n  end\nend\n","sourceCodeStart":30,"sourceCodeEnd":63,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/plugins/provisioners/salt/bootstrap_downloader.rb#L30-L63","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before (default: always chases 'latest', races .sha256 sidecar)\nconfig.vm.provision \"salt\" do |s|\n  s.install_master = true\nend\n\n# after (pin a local, pre-verified script)\n# curl -LO https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh\n# curl -LO .../bootstrap-salt.sh.sha256 && sha256sum -c bootstrap-salt.sh.sha256\nconfig.vm.provision \"salt\" do |s|\n  s.install_master = true\n  s.bootstrap_script_path = \"vendor/bootstrap-salt.sh\"\nend","handlingStrategy":"validation","validationCode":"# Pin and verify the bootstrap script on the host before provisioning\nrequire \"digest\"\nrequire \"open-uri\"\nscript = URI.open(\"https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh\")\nexpected = URI.open(\"https://github.com/saltstack/salt-bootstrap/releases/download/v2024.03.1/bootstrap-salt.sh.sha256\").read[/\\b([a-f0-9]{64})\\b/]\nabort \"sha mismatch\" unless Digest::SHA256.hexdigest(script.read) == expected\nFile.binwrite(\"vendor/bootstrap-salt.sh\", script.rewind && script.read)\n\nconfig.vm.provision \"salt\" do |s|\n  s.bootstrap_script_path = \"vendor/bootstrap-salt.sh\"\nend","typeGuard":"def bootstrap_script_verified?(path, sha256_file)\n  expected = File.read(sha256_file)[/\\b([a-f0-9]{64})\\b/]\n  Digest::SHA256.hexdigest(File.read(path)) == expected\nend","tryCatchPattern":"begin\n  env.cli(%w[provision])\nrescue VagrantPlugins::Salt::Errors::InvalidShasumError => e\n  # 'latest' release artifacts raced - clear caches and retry once\n  sleep 120\n  retry\nend","preventionTips":["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"],"tags":["salt","salt-bootstrap","provisioning","vagrant","checksum","sha256","supply-chain"],"backgroundTag":"sha256-checksum-mismatch","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}