hashicorp/vagrant · error · VagrantPlugins::Chef::Provisioner::Base::ChefError

Chef server provisioning requires that the `config.chef.chef

Error message

Chef server provisioning requires that the `config.chef.chef_server_url` be set to the
URL of your chef server. Examples include "http://12.12.12.12:4000" and
"http://example.com:4000" (the port of course can be different, but 4000 is the default)

What it means

Raised in ChefClient#configure when `config.chef.chef_server_url` is nil. Server-based provisioning writes this URL into the guest's client.rb (setup_server_config), so without it chef-client has no server to register against and converge with. Pure Vagrantfile configuration error, validated before any guest interaction.

Source

Thrown at plugins/provisioners/chef/provisioner/chef_client.rb:23

require 'vagrant'
require 'vagrant/util/presence'
require 'vagrant/util/subprocess'

require_relative "base"

module VagrantPlugins
  module Chef
    module Provisioner
      # This class implements provisioning via chef-client, allowing provisioning
      # with a chef server.
      class ChefClient < Base
        include Vagrant::Util::Presence

        def configure(root_config)
          raise ChefError, :server_validation_key_required if @config.validation_key_path.nil?
          raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path)
          raise ChefError, :server_url_required if @config.chef_server_url.nil?
        end

        def provision
          install_chef
          verify_binary(chef_binary_path("chef-client"))
          chown_provisioning_folder
          create_client_key_folder
          upload_validation_key
          upload_encrypted_data_bag_secret
          setup_json
          setup_server_config
          run_chef_client
          delete_encrypted_data_bag_secret
        end

        def cleanup
          if @config.delete_node
            delete_from_chef_server("node")

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Set the URL including organization: `chef.chef_server_url = "https://api.chef.io/organizations/myorg"`
  2. For self-hosted Infra Server include the port if non-standard, e.g. `https://chef.internal:443/organizations/myorg`
  3. Copy the exact value from your knife.rb / config.rb `chef_server_url` entry

Example fix

# Vagrantfile - before
config.vm.provision "chef_client" do |chef|
  chef.validation_key_path = "keys/myorg-validator.pem"
end

# Vagrantfile - after
config.vm.provision "chef_client" do |chef|
  chef.validation_key_path = "keys/myorg-validator.pem"
  chef.chef_server_url = "https://api.chef.io/organizations/myorg"
end
Defensive patterns

Strategy: validation

Validate before calling

# Derive all server settings from one source of truth (knife.rb / config.rb)
require "chef/config" if defined?(Chef)
chef_server = ENV.fetch("CHEF_SERVER_URL") # e.g. https://api.chef.io/organizations/myorg
abort "CHEF_SERVER_URL not set" if chef_server.nil?

config.vm.provision "chef_client" do |chef|
  chef.chef_server_url = chef_server
end

Type guard

def chef_client_config_valid?(chef)
  !chef.chef_server_url.nil? && !chef.validation_key_path.nil?
end

Prevention

When it happens

Trigger: Declaring a chef_client provisioner without `chef.chef_server_url`, e.g. after migrating from chef_solo and only keeping cookbooks_path settings.

Common situations: Migrating a chef_solo setup to chef-client; typos in the option name (chef_server_url vs server_url); forgetting the organization segment on hosted Chef (`/organizations/<org>`).

Related errors


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