hashicorp/vagrant · error · VagrantPlugins::CloudCommand::Errors::ServerError

The Vagrant Cloud server responded with a not-OK response:

Error message

The Vagrant Cloud server responded with a not-OK response:

%{errors}

What it means

Vagrant::Errors::ServerError is raised when Vagrant Cloud answers 400 Bad Request. The client JSON-parses the response body and joins its `errors` array into the message, so the text is the server's own validation feedback — typically a duplicate resource, an invalid field value, or a malformed payload.

Source

Thrown at plugins/commands/cloud/client/client.rb:194

      protected

      def with_error_handling(&block)
        yield
      rescue VagrantCloud::Error::ClientError => e
        @logger.debug("vagrantcloud request error:")
        @logger.debug(e.message)
        @logger.debug(e.backtrace.join("\n"))
        raise Errors::Unexpected, error: e.message
      rescue Excon::Error::Unauthorized
        @logger.debug("Unauthorized!")
        raise Errors::Unauthorized
      rescue Excon::Error::BadRequest => e
        @logger.debug("Bad request:")
        @logger.debug(e.message)
        @logger.debug(e.backtrace.join("\n"))
        parsed_response = JSON.parse(e.response.body)
        errors = parsed_response["errors"].join("\n")
        raise Errors::ServerError, errors: errors
      rescue Excon::Error::NotAcceptable => e
        @logger.debug("Got unacceptable response:")
        @logger.debug(e.message)
        @logger.debug(e.backtrace.join("\n"))

        parsed_response = JSON.parse(e.response.body)

        if two_factor = parsed_response['two_factor']
          store_two_factor_information two_factor

          if two_factor_default_delivery_method != APP
            request_code two_factor_default_delivery_method
          end

          raise Errors::TwoFactorRequired
        end

        begin

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Read the joined error lines in the message — they name the exact invalid field or conflict
  2. If the error is a duplicate, use the update variant (`vagrant cloud box update`, `vagrant cloud provider update`) or delete the existing resource first
  3. Correct the payload: semantic version format, supported checksum algorithm, well-formed https URL
  4. Re-run with VAGRANT_LOG=debug if the message was truncated or ambiguous

Example fix

# before
vagrant cloud provider create myorg/mybox virtualbox 1.0.0 --checksum-type sha123
# after
vagrant cloud provider create myorg/mybox virtualbox 1.0.0 --checksum-type sha256
Defensive patterns

Strategy: validation

Validate before calling

# Pre-validate the fields Vagrant Cloud rejects with 400 before calling the CLI
abort "bad version '#{version}'" unless version.match?(/\A\d+\.\d+\.\d+\S*\z/)
abort "bad checksum type" unless %w[md5 sha1 sha256 sha384 sha512].include?(checksum_type)
abort "bad url" unless url.nil? || url.start_with?("http://", "https://")

Try / catch

begin
  env.cli(%w[cloud provider create], org_box, provider, version, url)
rescue Vagrant::Errors::ServerError => e
  # e.message is the server's joined 'errors' array — one line per problem
  $stderr.puts "Vagrant Cloud rejected the payload:"
  e.message.each_line { |l| $stderr.puts "  #{l}" }
  exit 1
end

Prevention

When it happens

Trigger: POST/PUT requests whose payload fails server-side validation: creating a box that already exists (`vagrant cloud box create` on an existing org/box), an invalid version string, a checksum type outside md5/sha1/sha256/sha384/sha512, or an invalid provider URL during provider create/update/publish.

Common situations: Re-running a publish/create script after a partially successful first run (the box or version already exists); version typos like `1.0` instead of `1.0.0`; using an unsupported --checksum-type; scripts written against older, laxer API rules.

Related errors


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