basecamp/kamal · error · Kamal::ConfigurationError
The primary_role #{primary_role_name} isn't defined
Error message
The primary_role #{primary_role_name} isn't defined What it means
Kamal::Configuration#ensure_required_keys_present requires that the role named by `primary_role` actually exists among the keys of the `servers:` hash. The primary role (default "web", overridable via the top-level `primary_role:` key) is the role Kamal runs migrations, boot checks, and traffic switching against. If servers are defined but none matches the primary role name, configuration loading fails with the offending name interpolated into the message.
Source
Thrown at lib/kamal/configuration.rb:344
if require_destination? && destination.nil?
raise ArgumentError, "You must specify a destination"
end
true
end
def ensure_required_keys_present
%i[ service registry ].each do |key|
raise Kamal::ConfigurationError, "Missing required configuration for #{key}" unless raw_config[key].present?
end
raise Kamal::ConfigurationError, "Missing required configuration for image" if image.blank?
if raw_config.servers.nil?
raise Kamal::ConfigurationError, "No servers or accessories specified" unless raw_config.accessories.present?
else
unless role(primary_role_name).present?
raise Kamal::ConfigurationError, "The primary_role #{primary_role_name} isn't defined"
end
if primary_role.hosts.empty?
raise Kamal::ConfigurationError, "No servers specified for the #{primary_role.name} primary_role"
end
unless allow_empty_roles?
roles.each do |role|
if role.hosts.empty?
raise Kamal::ConfigurationError, "No servers specified for the #{role.name} role. You can ignore this with allow_empty_roles: true"
end
end
end
end
true
end
View on GitHub (pinned to eee0083b38)
Solutions
- Add a role matching the primary role name under `servers:` (e.g. a `web:` entry with at least one host).
- Or set `primary_role: <existing-role-name>` at the top level so it points at a role you actually defined.
- Double-check spelling and underscores — the match is exact against the servers hash keys.
- If ERB computes the role name, inspect the rendered config (`kamal config primary_role`) to see the resolved value.
Example fix
# config/deploy.yml — before
primary_role: app
servers:
web:
hosts:
- 1.2.3.4
# after
primary_role: app
servers:
app:
hosts:
- 1.2.3.4 Defensive patterns
Strategy: validation
Validate before calling
def primary_role_defined?(path = "config/deploy.yml")
raw = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) || {}
primary = raw["primary_role"] || "web"
raw["servers"].is_a?(Hash) && raw["servers"].key?(primary)
end Try / catch
begin
config = Kamal::Configuration.new(create_config_files: false)
rescue Kamal::ConfigurationError => e
puts "Deploy config invalid: #{e.message}"
exit 1
end Prevention
- Whenever you rename a servers role, grep the whole config for the old name, including primary_role and accessories.
- Set primary_role explicitly at the top of the config so the dependency is visible.
- Validate the rendered config (`kamal config`) in CI for every environment overlay.
When it happens
Trigger: Setting `primary_role: app` while `servers:` only defines roles like `web:` or `workers:`; renaming the `web` role to something else without updating `primary_role`; using a primary_role name from ERB/ENV that resolves with a typo or different capitalization.
Common situations: Renaming roles during a restructure and forgetting the cross-reference; copying a config that uses a custom primary_role name into a project whose servers hash still uses default naming; deleting the web role intending an accessory-only or worker-only setup.
Related errors
- No servers specified for the #{primary_role.name} primary_ro
- No servers specified for the #{role.name} role. You can igno
- Different roles can't share the same host for SSL: #{duplica
- Conflicting proxy run configurations for host #{host}
- accessories/#{name}: unknown roles #{missing_roles.join(", "
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/54be4101f5d1a129.
Report an issue: GitHub.