{"record":{"id":"d7c63419053af48d","repo":"basecamp/kamal","slug":"no-servers-specified-for-the-primary-role-name","errorCode":null,"errorMessage":"No servers specified for the #{primary_role.name} primary_role","messagePattern":"No servers specified for the #(.+?) primary_role","errorType":"validation","errorClass":"Kamal::ConfigurationError","httpStatus":null,"severity":"error","filePath":"lib/kamal/configuration.rb","lineNumber":348,"sourceCode":"      true\n    end\n\n    def ensure_required_keys_present\n      %i[ service registry ].each do |key|\n        raise Kamal::ConfigurationError, \"Missing required configuration for #{key}\" unless raw_config[key].present?\n      end\n\n      raise Kamal::ConfigurationError, \"Missing required configuration for image\" if image.blank?\n\n      if raw_config.servers.nil?\n        raise Kamal::ConfigurationError, \"No servers or accessories specified\" unless raw_config.accessories.present?\n      else\n        unless role(primary_role_name).present?\n          raise Kamal::ConfigurationError, \"The primary_role #{primary_role_name} isn't defined\"\n        end\n\n        if primary_role.hosts.empty?\n          raise Kamal::ConfigurationError, \"No servers specified for the #{primary_role.name} primary_role\"\n        end\n\n        unless allow_empty_roles?\n          roles.each do |role|\n            if role.hosts.empty?\n              raise Kamal::ConfigurationError, \"No servers specified for the #{role.name} role. You can ignore this with allow_empty_roles: true\"\n            end\n          end\n        end\n      end\n\n      true\n    end\n\n    def ensure_valid_service_name\n      raise Kamal::ConfigurationError, \"Service name can only include alphanumeric characters, hyphens, and underscores\" unless raw_config[:service] =~ /^[a-z0-9_-]+$/i\n\n      true","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/configuration.rb#L330-L366","documentation":"Kamal::Configuration#ensure_required_keys_present checks that the primary role — which does exist as a key under `servers:` — has a non-empty hosts list. A role entry with empty hosts (e.g. `web: { hosts: [] }` or an ERB-rendered empty array) means Kamal has no machine to run migrations, health checks, or traffic switching on, so validation aborts with the role name interpolated into the message.","triggerScenarios":"`servers: { web: { hosts: [] } }` after ERB renders an empty list because the source env var or loop produced nothing; a hosts list built from `<%= ENV[\"WEB_HOSTS\"]&.split(\",\") %>` that yields an empty array; a YAML role key with no hosts value at all.","commonSituations":"Templated multi-environment configs where one environment has no web hosts yet; stashing hosts in ENV and forgetting to export it in the deploy shell; refactoring hosts from an inline array to ERB and silently breaking it.","solutions":["Give the primary role at least one host: `web: { hosts: [ \"1.2.3.4\" ] }`.","If hosts come from ERB/ENV, make missing values fail loudly (raise in the template) instead of rendering an empty array.","Verify with `kamal config` (or `kamal config roles`) that the rendered hosts list is what you expect before deploying."],"exampleFix":"# config/deploy.yml — before\nservers:\n  web:\n    hosts: <%= ENV[\"WEB_HOSTS\"]&.split(\",\") %>\n\n# after\nservers:\n  web:\n    hosts: <%= (ENV[\"WEB_HOSTS\"] or raise \"WEB_HOSTS not set\").split(\",\") %>","handlingStrategy":"validation","validationCode":"def primary_role_has_hosts?(path = \"config/deploy.yml\")\n  raw = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) || {}\n  primary = raw[\"primary_role\"] || \"web\"\n  entry = raw[\"servers\"][primary] rescue nil\n  hosts = entry.is_a?(Hash) ? entry[\"hosts\"] : entry\n  Array(hosts).any? { |h| (h.is_a?(Hash) ? h.keys.first : h).to_s != \"\" }\nend","typeGuard":null,"tryCatchPattern":"begin\n  config = Kamal::Configuration.new(create_config_files: false)\nrescue Kamal::ConfigurationError => e\n  puts \"Deploy config invalid: #{e.message}\"\n  exit 1\nend","preventionTips":["Render host lists from ENV with explicit failure: `<%= ENV.fetch(\"WEB_HOSTS\") %>`.","Run `kamal config` after any change to ERB host templating.","Keep at least one staging/production host committed per environment overlay."],"tags":["kamal","configuration","servers","roles"],"backgroundTag":"empty-config-list","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}