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

The metadata for the box was malformed. The exact error is…

Error message

The metadata for the box was malformed. The exact error is shown below. Please contact the maintainer of the box so that this issue can be fixed.

%{error}

What it means

BoxMetadataMalformed is raised in BoxMetadata#initialize (lib/vagrant/box_metadata.rb:29) when JSON.load(io) on the catalog metadata raises JSON::ParserError. The parser's message is embedded, so the error shows exactly where the JSON is broken; it points at the metadata maintainer since the document is not valid JSON.

Solutions

  1. Fetch the exact URL with curl and inspect what is really returned: 'curl -sL -H "Accept: application/json" <metadata-url> | head'
  2. If you maintain the metadata, validate it (jq . metadata.json) and fix the reported JSON syntax error
  3. If a proxy/portal intercepts the request, whitelist the host or authenticate so JSON comes through
Defensive patterns

Strategy: validation

Validate before calling

require 'json'
require 'open-uri'
raw = URI.parse(metadata_url).open.read
JSON.parse(raw) # raises now, on your terms, if the catalog serves HTML/garbage

Prevention

When it happens

Trigger: BoxMetadata.new(io) is constructed from a downloaded or file-based metadata source (Box#load_metadata after download, or reading a catalog file) whose content is not parseable JSON — HTML login/error page, truncated body, trailing commas, BOM.

Common situations: Self-hosted catalog behind a proxy that returns an HTML block page; internal web server misconfigured to serve the URL as a directory listing; hand-edited metadata.json with a trailing comma; CDN serving partial content.

Understand the failure class

Related errors


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

Appendix: source

Thrown at lib/vagrant/box_metadata.rb:29

    # The name that the box should be if it is added.
    #
    # @return [String]
    attr_accessor :name

    # The long-form human-readable description of a box.
    #
    # @return [String]
    attr_accessor :description

    # Loads the metadata associated with the box from the given
    # IO.
    #
    # @param [IO] io An IO object to read the metadata from.
    def initialize(io, **_)
      begin
        @raw = JSON.load(io)
      rescue JSON::ParserError => e
        raise Errors::BoxMetadataMalformed,
          error: e.to_s
      end

      @raw ||= {}
      @name = @raw["name"]
      @description = @raw["description"]
      @version_map = (@raw["versions"] || []).map do |v|
        begin
          [Gem::Version.new(v["version"]), Version.new(v)]
        rescue ArgumentError
          raise Errors::BoxMetadataMalformedVersion,
            version: v["version"].to_s
        end
      end
      @version_map = Hash[@version_map]
    end

    # Returns data about a single version that is included in this

View on GitHub (pinned to 35f3160f4a)