basecamp/kamal · error · Kamal::ConfigurationError
#{error_context}#{message}
Error message
#{error_context}#{message} What it means
This is the single raise point for every deploy.yml schema validation failure in Kamal. The final message is the validation context path (e.g. "accessories/db:") joined with the concrete problem, such as "unknown key: xyz" or "should be a String or Symbol". It means Kamal parsed your YAML but a key or value does not match the configuration schema for that section.
Source
Thrown at lib/kamal/configuration/validator.rb:184
def validate_hooks_output!(value)
# hooks_output can be either a symbol/string (global) or a hash (per-hook)
if value.is_a?(Hash)
value.each do |hook, level|
with_context(hook) do
validate_type! level, String, Symbol
end
end
else
validate_type! value, String, Symbol
end
end
def validate_type!(value, *types)
type_error(*types) unless types.any? { |type| valid_type?(value, type) }
end
def error(message)
raise Kamal::ConfigurationError, "#{error_context}#{message}"
end
def type_error(*expected_types)
descriptions = expected_types.map { |type| type_description(type) }.uniq
error "should be #{descriptions.join(" or ")}"
end
def unknown_keys_error(unknown_keys)
error "unknown #{"key".pluralize(unknown_keys.count)}: #{unknown_keys.join(", ")}"
end
def error_context
"#{context}: " if context.present?
end
def with_context(context)
old_context = @context
@context = [ @context, context ].select(&:present?).join("/")View on GitHub (pinned to eee0083b38)
Solutions
- Read the context prefix before the colon in the message to locate the failing section, then fix or delete the offending key shown after it
- Run kamal config (or kamal config show) to re-trigger validation and inspect the effective config once it parses
- Diff your deploy.yml against the shipped template (kamal init produces config/deploy.yml) or the docs for your installed Kamal version
- For type errors ("should be ..."), re-indent the YAML so the value is the expected mapping/array/scalar
Example fix
# deploy.yml (before)
servers:
web:
host: 1.2.3.4 # unknown key, should be hosts
# deploy.yml (after)
servers:
web:
hosts:
- 1.2.3.4 Defensive patterns
Strategy: validation
Validate before calling
# CI step: validate deploy.yml parses against kamal's own validator
system("kamal config > /dev/null") or abort "deploy.yml is invalid — see kamal config output" Prevention
- Run `kamal config` as a CI check on every change to config/deploy*.yml
- Pin the kamal gem version in Gemfile and re-validate config after upgrades (option names change between major versions)
- Start new apps from `kamal init`'s generated config to get the current schema
When it happens
Trigger: Any invalid deploy.yml entry: a typo'd key like enviroment: (unknown_keys_error), a wrong value type such as servers: "1.2.3.4" instead of a hash/array (type_error via validate_type!), or invalid nested proxy/registry/accessory settings. Raised when Kamal::Configuration is instantiated, i.e. on essentially every kamal command.
Common situations: Typos in YAML keys; copying example configs from docs of a different Kamal version (e.g. kamal v1 vs v2 renames); indentation mistakes that turn a mapping into a string; leaving experimental or removed options in the file after an upgrade.
Related errors
- Missing required configuration for #{key}
- Missing required configuration for image
- No servers or accessories specified
- Service name can only include alphanumeric characters, hyphe
- Invalid hooks_output '#{level}'#{context}, must be one of: #
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/4e9942bc29f8fd22.
Report an issue: GitHub.