basecamp/kamal · error · ArgumentError
Invalid builder configuration: the `docker` driver does not
Error message
Invalid builder configuration: the `docker` driver does not not support remote builders
What it means
Kamal::Configuration::Builder#valid? rejects combinations where `driver: docker` (the plain Docker builder rather than docker-container/buildx) is used together with `remote:`. The plain docker driver runs builds inside the local Docker daemon, so it cannot dispatch builds to a remote builder; Kamal raises this ArgumentError at configuration load to prevent a nonsensical build setup.
Source
Thrown at lib/kamal/configuration/builder.rb:162
end
def build_directory
@build_directory ||=
if git_clone?
File.join clone_directory, repo_basename, repo_relative_pwd
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_optionsView on GitHub (pinned to eee0083b38)
Solutions
- Remove the `remote:` key when using `driver: docker` — builds will run in the local Docker daemon.
- Or keep the remote builder but drop `driver: docker` so the default buildx/docker-container driver handles remote dispatch.
- If layering configs, audit the merged result (`kamal config`) to confirm the driver/remote pair is intentional.
Example fix
# config/deploy.yml — before builder: driver: docker remote: ssh://buildhost # after builder: driver: docker
Defensive patterns
Strategy: validation
Validate before calling
def builder_driver_remote_compatible?(raw)
b = raw["builder"] || {}
!(b["driver"] == "docker" && b["remote"])
end Type guard
def docker_driver_config?(builder_cfg)
builder_cfg.is_a?(Hash) && builder_cfg["driver"] == "docker" &&
!builder_cfg["remote"] && !builder_cfg.dig("cache", "type") &&
Array(builder_cfg["arches"]).size <= 1
end Try / catch
begin
Kamal::Configuration.new(create_config_files: false)
rescue ArgumentError, Kamal::ConfigurationError => e
abort "#{e.message}"
end Prevention
- Never combine driver: docker with remote, cache, or multi-arch.
- Review merged builder config (`kamal config`) when layering environment overlays.
- Prefer omitting `driver` unless you specifically need the plain docker builder.
When it happens
Trigger: `builder: { driver: docker, remote: ssh://user@buildhost }` in config/deploy.yml; keeping a remote: URL from a previous buildx setup after switching driver to docker; merging environment overrides that add remote while a base config pins driver: docker.
Common situations: Experimenting with the docker driver for speed (it avoids QEMU/build containers) while forgetting to strip remote builder config; layered configs (deploy.yml + deploy.production.yml) combining incompatible keys.
Related errors
- Invalid builder configuration: the `docker` driver does not
- Invalid builder configuration: the `docker` driver does not
- Local registry with remote builder requires an SSH URL (e.g.
- Invalid cache type: #{@options["cache"]["type"]}
- 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/54892b969fa9ba86.
Report an issue: GitHub.