{"record":{"id":"6605b93c7a389f81","repo":"hashicorp/vagrant","slug":"chef-never-successfully-completed-any-errors-shou-6605b9","errorCode":null,"errorMessage":"Chef never successfully completed! Any errors should be visible in the\noutput above. Please fix your recipes so that they properly complete.","messagePattern":"Chef never successfully completed! Any errors should be visible in the\noutput above\\. Please fix your recipes so that they properly complete\\.","errorType":"exception","errorClass":"VagrantPlugins::Chef::Provisioner::Base::ChefError","httpStatus":null,"severity":"error","filePath":"plugins/provisioners/chef/provisioner/chef_solo.rb","lineNumber":223,"sourceCode":"\n              opts = { error_check: false, elevated: true }\n              exit_status = @machine.communicate.sudo(command, opts) do |type, data|\n                # Output the data with the proper color based on the stream.\n                color = type == :stdout ? :green : :red\n\n                data = data.chomp\n                next if data.empty?\n\n                @machine.ui.info(data, color: color)\n              end\n\n              # There is no need to run Chef again if it converges\n              return if exit_status == 0\n            end\n          end\n\n          # If we reached this point then Chef never converged! Error.\n          raise ChefError, :no_convergence\n        end\n\n        def verify_shared_folders(folders)\n          folders.each do |folder|\n            @logger.debug(\"Checking for shared folder: #{folder}\")\n            if !@machine.communicate.test(\"test -d #{folder}\", sudo: true)\n              raise ChefError, :missing_shared_folders\n            end\n          end\n        end\n\n        protected\n\n        # Extracts only the remote paths from a list of folders\n        def guest_paths(folders)\n          folders.map { |parts| parts[2] }\n        end\n      end","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/plugins/provisioners/chef/provisioner/chef_solo.rb#L205-L241","documentation":"Raised at the end of run_chef_solo in the chef_solo provisioner: identical convergence loop to chef_client (exit 259 = reboot and re-run, exit 0 = success, up to `config.attempts` iterations). Solo runs chef-solo against local cookbooks mounted from the host, so non-convergence means recipe failure, missing local cookbooks/roles/data bags, or bad solo.rb inputs - all visible in the streamed output above.","triggerScenarios":"chef-solo exiting non-zero on all attempts: recipe errors, `cookbooks_path` pointing at a folder without the needed cookbook, missing roles/environments/data bags, Ruby/Chef version mismatch inside the guest.","commonSituations":"cookbooks_path typo or folder not synced into guest; dependency cookbooks not vendored (no Berkshelf/Librarian step); role files referenced but roles_path unset; node attributes with wrong types causing compile errors.","solutions":["Read the chef-solo output above - fix the first reported resource or compile error","Verify cookbook layout: `chef.cookbooks_path = \"cookbooks\"` must contain the cookbooks named in run_list","Vendor dependencies first (berks vendor cookbooks) and point cookbooks_path at the vendored folder","Set `chef.attempts = 3` for transient failures such as package mirror hiccups"],"exampleFix":"# Vagrantfile - before\nchef.cookbooks_path = \"../chef-repo/cookbooks\"\nchef.run_list = [\"recipe[apache2]\"]  # apache2 not in that folder\n\n# Vagrantfile - after\nchef.cookbooks_path = [\"cookbooks\", \"site-cookbooks\"]\nchef.run_list = [\"recipe[apache2]\"]   # berks vendor'd into ./cookbooks","handlingStrategy":"retry","validationCode":"# Verify the run_list resolves against your local cookbooks before provisioning\nrecipes = chef.run_list.map { |r| r.split(\"[\").last.split(\"]\").first }\ncookbooks = Dir.children(\"cookbooks\")\nmissing = recipes.reject { |recipe_dir_name| cookbooks.include?(recipe_dir_name) }\nabort \"Missing cookbooks: #{missing.join(', ')}\" unless missing.empty?","typeGuard":null,"tryCatchPattern":"begin\n  env.cli(%w[provision])\nrescue Vagrant::Errors::VagrantError => e\n  if e.to_s.include?(\"never successfully completed\")\n    dump_chef_log_and_fail!  # vagrant ssh -c 'cat /var/log/chef-solo.log'\n  end\n  raise\nend","preventionTips":["Vendor dependencies (berks vendor) and point cookbooks_path at the vendored dir so solo never misses cookbooks","Test cookbooks with Test Kitchen or chef-zero locally before putting them in a Vagrantfile run_list","Keep chef.attempts >= 2 for recipes that install from the network"],"tags":["chef","chef-solo","provisioning","vagrant","convergence"],"backgroundTag":"chef-convergence-failure","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}