basecamp/kamal · error · Kamal::ConfigurationError
Conflicting proxy run configurations for host #{host}
Error message
Conflicting proxy run configurations for host #{host} What it means
Kamal::Configuration#ensure_no_conflicting_proxy_runs gathers, for every host, the proxy `run` option hash from each role and accessory present on that host (via proxy_runs, which maps host_roles(host) plus host_accessories(host) to their proxy.run). If the same host receives more than one distinct run configuration, Kamal cannot decide which custom docker run options to launch the proxy with, so it raises with the host name.
Source
Thrown at lib/kamal/configuration.rb:422
true
end
def ensure_local_registry_remote_builder_has_ssh_url
if registry.local? && builder.remote?
unless URI(builder.remote).scheme == "ssh"
raise Kamal::ConfigurationError, "Local registry with remote builder requires an SSH URL (e.g., ssh://user@host)"
end
end
true
end
def ensure_no_conflicting_proxy_runs
all_hosts.each do |host|
run_configs = proxy_runs(host)
if run_configs.uniq.size > 1
raise Kamal::ConfigurationError, "Conflicting proxy run configurations for host #{host}"
end
end
end
def proxy_runs(host)
(host_roles(host) + host_accessories(host)).map(&:proxy).compact.map(&:run).compact
end
def role_names
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
end
def ensure_valid_hooks_output!
case raw_config.hooks_output
when Symbol, String
validate_hooks_output_level!(raw_config.hooks_output.to_sym)
when Hash
raw_config.hooks_output.each { |hook, level| validate_hooks_output_level!(level.to_sym, hook) }View on GitHub (pinned to eee0083b38)
Solutions
- Inspect `kamal config` for each role/accessory on the failing host and make their `proxy: { run: }` hashes identical — usually by defining run options once at the top-level proxy and removing per-role overrides.
- Or move the differing role/accessory to a separate host.
- If the difference is unintentional (stale copy-paste), delete the duplicate run block so all entries on that host agree.
Example fix
# config/deploy.yml — before
servers:
web:
hosts: [ "1.2.3.4" ]
proxy:
run:
network: app-net
api:
hosts: [ "1.2.3.4" ]
proxy:
run:
network: api-net
# after
proxy:
run:
network: app-net
servers:
web:
hosts: [ "1.2.3.4" ]
api:
hosts: [ "1.2.3.4" ] Defensive patterns
Strategy: validation
Validate before calling
def proxy_runs_uniq?(raw)
hosts_to_run = Hash.new { |h, k| h[k] = [] }
raw["servers"].to_a.each do |_name, entry|
next unless entry.is_a?(Hash)
run = entry.dig("proxy", "run")
hosts = entry["hosts"] || entry
Array(hosts).each do |h|
host = h.is_a?(Hash) ? h.keys.first : h
hosts_to_run[host] << run
end
end
hosts_to_run.values.all? { |runs| runs.compact.uniq.size <= 1 }
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
- Define proxy run options once at the top level instead of per role.
- When two roles share a host, diff their proxy blocks before deploying.
- Use `kamal config` to review the merged proxy settings for shared hosts.
When it happens
Trigger: Two roles sharing a host where each sets a different `proxy: { run: }` block (e.g. different network or labels); an accessory on the same host as a web role defining its own proxy.run that differs from the role's; per-role proxy run overrides added during an upgrade while the global proxy config still differs.
Common situations: Custom proxy run options (logging, ulimits, networks) rolled out per role; accessories like a monitoring agent attaching to the proxy; consolidating roles onto one machine making previously-divergent run configs collide.
Related errors
- Different roles can't share the same host for SSL: #{duplica
- accessories/#{name}: unknown roles #{missing_roles.join(", "
- accessories/#{name}: unknown role #{accessory_config["role"]
- The primary_role #{primary_role_name} isn't defined
- No servers specified for the #{primary_role.name} primary_ro
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/d992bef5616d4e7e.
Report an issue: GitHub.