hashicorp/vagrant · error · Vagrant::Errors::BoxChecksumMismatch

The checksum of the downloaded box did not match the expecte

Error message

The checksum of the downloaded box did not match the expected
value. Please verify that you have the proper URL setup and that
you're downloading the proper file.

Expected: %{expected}
Received: %{actual}

What it means

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.

Source

Thrown at lib/vagrant/action/builtin/box_add.rb:674

            return false
          end

          output = d.head
          match  = output.scan(/^Content-Type: (.+?)$/i).last
          return false if !match
          !!(match.last.chomp =~ /application\/json/)
        end

        def validate_checksum(checksum_type, _checksum, path)
          checksum = _checksum.strip()
          @logger.info("Validating checksum with #{checksum_type}")
          @logger.info("Expected checksum: #{checksum}")

          _actual = FileChecksum.new(path, checksum_type).checksum
          actual = _actual.strip()
          @logger.info("Actual checksum: #{actual}")
          if actual.casecmp(checksum) != 0
            raise Errors::BoxChecksumMismatch,
              actual: actual,
              expected: checksum
          end
        end
      end
    end
  end
end

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Recompute the checksum of the served file (curl + sha256sum) and compare with your --checksum value.
  2. Confirm --checksum-type matches how the expected digest was produced (md5/sha1/sha256/sha384/sha512).
  3. If the file changed upstream, update the checksum to the new published value.
  4. Delete any partial download and retry; if it still mismatches, treat the source as untrusted and stop.

Example fix

# before
vagrant box add \
  --checksum 9d3e2c...  \
  --checksum-type sha256 \
  https://example.com/ubuntu-22.04.box   # server now ships a rebuilt file -> BoxChecksumMismatch

# after: verify what the server actually serves and align
shasum -a 256 <(curl -sL https://example.com/ubuntu-22.04.box)
vagrant box add --checksum <fresh-digest> --checksum-type sha256 https://example.com/ubuntu-22.04.box
Defensive patterns

Strategy: try-catch

Validate before calling

# Verify the served file's digest before handing it to vagrant
require "digest"
digest = Digest::SHA256.file(download_to_tmp(url)).hexdigest
abort "source changed" unless digest.casecmp?(expected)

Type guard

def checksum_matches?(path, expected, type = :sha256)
  Digest.const_get(type.to_s.upcase).file(path).hexdigest.casecmp?(expected.strip)
end

Try / catch

begin
  env.cli("box", "add", "--checksum", sum, "--checksum-type", "sha256", url)
rescue Vagrant::Errors::BoxChecksumMismatch => e
  # e.extra_data[:expected] vs [:actual]
  abort "served file digest #{e.extra_data[:actual]} != pinned #{e.extra_data[:expected]} - source is untrusted"
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21). Data as JSON: /api/errors/c7874e5fd8e03581. Report an issue: GitHub.