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
endView on GitHub (pinned to eee0083b38)
Solutions
- Add a top-level `image: your-app-name` key to config/deploy.yml (Kamal tags it as registry/.../image:version at push time).
- If the value is ERB-interpolated, verify the referenced ENV var is set in every environment that runs kamal, CI shells included.
- Check YAML indentation — `image` must be a sibling of `service` and `servers`, not nested under them.
- 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
- Keep a CI step that runs `kamal config` (or loads Kamal::Configuration) on every config change.
- Make ERB-interpolated values raise loudly when their ENV var is unset instead of rendering blank.
- Use a config schema checklist (service, image, registry, servers) reviewed at project setup.
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
- No servers or accessories specified
- #{error_context}#{message}
- Hook `#{hook}` failed:\n#{e.message}
- Failed to get endpoint for #{role} on #{host}, did the conta
- Failed to get endpoint for #{role} on #{host}, did the conta
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/ae496df46a3b689b.
Report an issue: GitHub.