{"record":{"id":"c7874e5fd8e03581","repo":"hashicorp/vagrant","slug":"the-checksum-of-the-downloaded-box-did-not-match-t","errorCode":null,"errorMessage":"The checksum of the downloaded box did not match the expected\nvalue. Please verify that you have the proper URL setup and that\nyou're downloading the proper file.\n\nExpected: %{expected}\nReceived: %{actual}","messagePattern":"The checksum of the downloaded box did not match the expected\nvalue\\. Please verify that you have the proper URL setup and that\nyou're downloading the proper file\\.\n\nExpected: %(.+?)\nReceived: %(.+?)","errorType":"exception","errorClass":"Vagrant::Errors::BoxChecksumMismatch","httpStatus":null,"severity":"error","filePath":"lib/vagrant/action/builtin/box_add.rb","lineNumber":674,"sourceCode":"            return false\n          end\n\n          output = d.head\n          match  = output.scan(/^Content-Type: (.+?)$/i).last\n          return false if !match\n          !!(match.last.chomp =~ /application\\/json/)\n        end\n\n        def validate_checksum(checksum_type, _checksum, path)\n          checksum = _checksum.strip()\n          @logger.info(\"Validating checksum with #{checksum_type}\")\n          @logger.info(\"Expected checksum: #{checksum}\")\n\n          _actual = FileChecksum.new(path, checksum_type).checksum\n          actual = _actual.strip()\n          @logger.info(\"Actual checksum: #{actual}\")\n          if actual.casecmp(checksum) != 0\n            raise Errors::BoxChecksumMismatch,\n              actual: actual,\n              expected: checksum\n          end\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":656,"sourceCodeEnd":683,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/action/builtin/box_add.rb#L656-L683","documentation":"Errors::BoxChecksumMismatch is raised by validate_checksum after the box file lands on disk: the digest computed from the downloaded file (FileChecksum with the given checksum_type) does not equal the expected value the user supplied (--checksum), compared case-insensitively.","triggerScenarios":"Call vagrant box add with --checksum and --checksum-type; after download, validate_checksum computes FileChecksum.new(path, checksum_type).checksum and actual.casecmp(checksum) != 0, raising with actual and expected strings.","commonSituations":"The mirror/URL serves a different build than the checksum was cut from; the checksum was copied for the wrong version or wrong checksum type (md5 vs sha256); a truncated or corrupted download; rarely, a genuinely tampered file.","solutions":["Recompute the checksum of the served file (curl + sha256sum) and compare with your --checksum value.","Confirm --checksum-type matches how the expected digest was produced (md5/sha1/sha256/sha384/sha512).","If the file changed upstream, update the checksum to the new published value.","Delete any partial download and retry; if it still mismatches, treat the source as untrusted and stop."],"exampleFix":"# before\nvagrant box add \\\n  --checksum 9d3e2c...  \\\n  --checksum-type sha256 \\\n  https://example.com/ubuntu-22.04.box   # server now ships a rebuilt file -> BoxChecksumMismatch\n\n# after: verify what the server actually serves and align\nshasum -a 256 <(curl -sL https://example.com/ubuntu-22.04.box)\nvagrant box add --checksum <fresh-digest> --checksum-type sha256 https://example.com/ubuntu-22.04.box","handlingStrategy":"try-catch","validationCode":"# Verify the served file's digest before handing it to vagrant\nrequire \"digest\"\ndigest = Digest::SHA256.file(download_to_tmp(url)).hexdigest\nabort \"source changed\" unless digest.casecmp?(expected)","typeGuard":"def checksum_matches?(path, expected, type = :sha256)\n  Digest.const_get(type.to_s.upcase).file(path).hexdigest.casecmp?(expected.strip)\nend","tryCatchPattern":"begin\n  env.cli(\"box\", \"add\", \"--checksum\", sum, \"--checksum-type\", \"sha256\", url)\nrescue Vagrant::Errors::BoxChecksumMismatch => e\n  # e.extra_data[:expected] vs [:actual]\n  abort \"served file digest #{e.extra_data[:actual]} != pinned #{e.extra_data[:expected]} - source is untrusted\"\nend","preventionTips":["Always pass --checksum-type alongside --checksum so the digest algorithm is unambiguous.","Pin checksums to immutable artifact URLs (versioned filenames), not mutable 'latest' paths.","Treat a mismatch as a security signal - never bypass it with a re-download from an unverified mirror."],"tags":["vagrant","box-add","checksum","integrity","download"],"backgroundTag":"checksum-mismatch","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}