basecamp/kamal · error · Kamal::ConfigurationError

Missing required configuration for image

Error message

Missing required configuration for image

What it means

Kamal raises this Kamal::ConfigurationError while loading config/deploy.yml, in ensure_required_keys_present. After verifying that the required `service` and `registry` keys exist, it checks that an `image` is present, because Kamal needs the name of the Docker image to build, tag, and push to the registry. The image value comes from raw_config[:image], so a missing or blank value means deploys, builds, and pushes have no image reference to operate on.

Source

Thrown at lib/kamal/configuration.rb:338

    }.compact
  end

  private
    # Will raise ArgumentError if any required config keys are missing
    def ensure_destination_if_required
      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

View on GitHub (pinned to eee0083b38)

Solutions

  1. Add a top-level `image: your-app-name` key to config/deploy.yml (Kamal tags it as registry/.../image:version at push time).
  2. If the value is ERB-interpolated, verify the referenced ENV var is set in every environment that runs kamal, CI shells included.
  3. Check YAML indentation — `image` must be a sibling of `service` and `servers`, not nested under them.
  4. If overriding config per environment (config/deploy.production.yml), confirm the merge still yields an `image`.

Example fix

# config/deploy.yml — before
service: myapp
registry: registry.example.com
servers:
  web:
    - 1.2.3.4

# after
service: myapp
image: myapp
registry: registry.example.com
servers:
  web:
    - 1.2.3.4
Defensive patterns

Strategy: validation

Validate before calling

require "yaml"
require "erb"

def config_ready_for_kamal?(path = "config/deploy.yml")
  raw = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) || {}
  %w[service registry].all? { |k| raw[k].to_s.strip != "" } && raw["image"].to_s.strip != ""
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

When it happens

Trigger: Running any Kamal command (e.g. `kamal deploy`, `kamal build`) with a config/deploy.yml that has no top-level `image:` key, an `image:` set to nil/empty string, or an ERB-templated `image: <%= ENV["IMAGE"] %>` where the environment variable is unset so it renders blank.

Common situations: New Kamal setups copied from a tutorial that omits `image`; configs migrated from kamal 1.x where keys were reshuffled and `image` was dropped; ERB interpolation depending on an env var missing in CI; YAML indentation putting `image` under the wrong parent key.

Related errors


AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21). Data as JSON: /api/errors/ae496df46a3b689b. Report an issue: GitHub.