{"record":{"id":"d992bef5616d4e7e","repo":"basecamp/kamal","slug":"conflicting-proxy-run-configurations-for-host-ho","errorCode":null,"errorMessage":"Conflicting proxy run configurations for host #{host}","messagePattern":"Conflicting proxy run configurations for host #(.+?)","errorType":"validation","errorClass":"Kamal::ConfigurationError","httpStatus":null,"severity":"error","filePath":"lib/kamal/configuration.rb","lineNumber":422,"sourceCode":"\n      true\n    end\n\n    def ensure_local_registry_remote_builder_has_ssh_url\n      if registry.local? && builder.remote?\n        unless URI(builder.remote).scheme == \"ssh\"\n          raise Kamal::ConfigurationError, \"Local registry with remote builder requires an SSH URL (e.g., ssh://user@host)\"\n        end\n      end\n\n      true\n    end\n\n    def ensure_no_conflicting_proxy_runs\n      all_hosts.each do |host|\n        run_configs = proxy_runs(host)\n        if run_configs.uniq.size > 1\n          raise Kamal::ConfigurationError, \"Conflicting proxy run configurations for host #{host}\"\n        end\n      end\n    end\n\n    def proxy_runs(host)\n      (host_roles(host) + host_accessories(host)).map(&:proxy).compact.map(&:run).compact\n    end\n\n    def role_names\n      raw_config.servers.is_a?(Array) ? [ \"web\" ] : raw_config.servers.keys.sort\n    end\n\n    def ensure_valid_hooks_output!\n      case raw_config.hooks_output\n      when Symbol, String\n        validate_hooks_output_level!(raw_config.hooks_output.to_sym)\n      when Hash\n        raw_config.hooks_output.each { |hook, level| validate_hooks_output_level!(level.to_sym, hook) }","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/configuration.rb#L404-L440","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# config/deploy.yml — before\nservers:\n  web:\n    hosts: [ \"1.2.3.4\" ]\n    proxy:\n      run:\n        network: app-net\n  api:\n    hosts: [ \"1.2.3.4\" ]\n    proxy:\n      run:\n        network: api-net\n\n# after\nproxy:\n  run:\n    network: app-net\nservers:\n  web:\n    hosts: [ \"1.2.3.4\" ]\n  api:\n    hosts: [ \"1.2.3.4\" ]","handlingStrategy":"validation","validationCode":"def proxy_runs_uniq?(raw)\n  hosts_to_run = Hash.new { |h, k| h[k] = [] }\n  raw[\"servers\"].to_a.each do |_name, entry|\n    next unless entry.is_a?(Hash)\n    run = entry.dig(\"proxy\", \"run\")\n    hosts = entry[\"hosts\"] || entry\n    Array(hosts).each do |h|\n      host = h.is_a?(Hash) ? h.keys.first : h\n      hosts_to_run[host] << run\n    end\n  end\n  hosts_to_run.values.all? { |runs| runs.compact.uniq.size <= 1 }\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":["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."],"tags":["kamal","proxy","configuration","roles","accessories"],"backgroundTag":"conflicting-config-entries","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}