{"record":{"id":"42a108378441266c","repo":"basecamp/kamal","slug":"no-servers-or-accessories-specified","errorCode":null,"errorMessage":"No servers or accessories specified","messagePattern":"No servers or accessories specified","errorType":"validation","errorClass":"Kamal::ConfigurationError","httpStatus":null,"severity":"error","filePath":"lib/kamal/configuration.rb","lineNumber":341,"sourceCode":"  private\n    # Will raise ArgumentError if any required config keys are missing\n    def ensure_destination_if_required\n      if require_destination? && destination.nil?\n        raise ArgumentError, \"You must specify a destination\"\n      end\n\n      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","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/configuration.rb#L323-L359","documentation":"Raised by Kamal::Configuration#ensure_required_keys_present when the `servers:` section of config/deploy.yml is nil (key absent or explicitly null) and no `accessories:` are defined either. Kamal requires at least one deployment target — either server roles to deploy the app to, or accessories (auxiliary containers like Redis) to run. With neither, there is nothing for Kamal to do, so configuration loading aborts.","triggerScenarios":"`kamal deploy` or `kamal setup` with a config/deploy.yml that defines service/registry/image but omits `servers:` entirely and defines no `accessories:`; setting `servers:` to null via ERB that renders nothing; a heavily trimmed config used only for `kamal build` that still goes through full validation.","commonSituations":"Boilerplate configs where the servers block was deleted pending real hostnames; ERB-conditional servers blocks that render empty in CI; converting a full deploy config into a build-only config without realizing validation is global.","solutions":["Add a `servers:` block with at least one role and host, e.g. `servers: { web: [ \"1.2.3.4\" ] }`.","If you genuinely have no app servers, define at least one accessory so the configuration is a valid accessory-only deploy.","Fix ERB templates that can render `servers:` as null — fail loudly when host input is missing."],"exampleFix":"# config/deploy.yml — before\nservice: myapp\nregistry: registry.example.com\n\n# after\nservice: myapp\nregistry: registry.example.com\nservers:\n  web:\n    - 1.2.3.4","handlingStrategy":"validation","validationCode":"def deployable_config?(path = \"config/deploy.yml\")\n  raw = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) || {}\n  !raw[\"servers\"].nil? || raw[\"accessories\"].to_s.strip != \"\"\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":["Template servers via ERB only with a guard that raises when host lists are empty.","Run `kamal config` locally before pushing config changes.","Treat a config with neither servers nor accessories as a template, and keep it out of environments that deploy."],"tags":["kamal","configuration","servers","deploy"],"backgroundTag":"missing-required-config-key","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}