basecamp/kamal · error · ArgumentError
Invalid cache type: #{@options["cache"]["type"]}
Error message
Invalid cache type: #{@options["cache"]["type"]} What it means
Kamal::Configuration::Builder#valid? checks that when a cache type is configured (`builder.cache.type` present), it is one of exactly "gha" (GitHub Actions cache) or "registry" (cache image in the container registry). Any other string raises this ArgumentError with the offending value, since Kamal only knows how to wire those two buildx cache backends.
Source
Thrown at lib/kamal/configuration/builder.rb:168
else
"."
end
end
def docker_driver?
driver == "docker"
end
private
def valid?
if docker_driver?
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
end
if @options["cache"] && @options["cache"]["type"]
raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
end
end
def cache_image
builder_config["cache"]&.fetch("image", nil) || "#{image}-build-cache"
end
def cache_image_ref
[ server, cache_image ].compact.join("/")
end
def cache_options
builder_config["cache"]&.fetch("options", nil)
end
def cache_from_config_for_gha
individual_options = cache_options&.split(",") || []
allowed_options = individual_options.select { |option| option =~ /^(url|url_v2|token|scope|timeout)=/ }View on GitHub (pinned to eee0083b38)
Solutions
- Set `cache.type` to `gha` or `registry` exactly (lowercase).
- Choose gha when deploying from GitHub Actions; registry when an ordinary registry-backed cache fits all environments.
- If the value is ENV-driven, whitelist it: `<%= %w[gha registry].include?(ENV["CACHE_TYPE"]) ? ENV["CACHE_TYPE"] : "registry" %>`.
Example fix
# config/deploy.yml — before
builder:
cache:
type: s3
# after
builder:
cache:
type: gha Defensive patterns
Strategy: validation
Validate before calling
CACHE_TYPES = %w[gha registry].freeze
def valid_cache_type?(raw)
type = raw.dig("builder", "cache", "type")
type.nil? || CACHE_TYPES.include?(type)
end Type guard
def kamal_cache_type?(value) %w[gha registry].include?(value.to_s) end
Try / catch
begin
Kamal::Configuration.new(create_config_files: false)
rescue ArgumentError, Kamal::ConfigurationError => e
abort "#{e.message} — cache type must be gha or registry"
end Prevention
- Use gha only in GitHub Actions pipelines; registry elsewhere.
- Whitelist ENV-driven cache types in ERB templates.
- Re-check allowed values after kamal upgrades — the list lives in Kamal::Configuration::Builder#valid?.
When it happens
Trigger: `builder: { cache: { type: local } }` or `type: s3` in config/deploy.yml; typos like a trailing space, `GHA`, or `Registry` (the check is case-sensitive); ENV-sourced cache types such as `<%= ENV["CACHE_TYPE"] %>` resolving to something unsupported.
Common situations: Copy-pasting buildx CLI cache type names that kamal does not expose; case mismatches from environment variables; stale docs or invented values in shared config templates.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid builder configuration: the `docker` driver does not
- Missing required configuration for #{key}
- Service name can only include alphanumeric characters, hyphe
- Local registry with remote builder requires an SSH URL (e.g.
- Invalid hooks_output '#{level}'#{context}, must be one of: #
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/101fb78c179d7506.
Report an issue: GitHub.