docker/compose · error
invalid ssh key %q
Error message
invalid ssh key %q
What it means
--ssh expects either the bare keyword `default` (forward the agent) or an ID=PATH pair such as mykey=/home/me/.ssh/id_rsa. toAPIBuildOptions splits on '='; if there is no '=' and the value is not exactly 'default', the ID cannot be determined and build option construction fails before BuildKit is contacted.
Source
Thrown at cmd/compose/build.go:58
push bool
args []string
noCache bool
memory cliopts.MemBytes
ssh string
builder string
deps bool
print bool
check bool
sbom string
provenance string
}
func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions, error) {
var SSHKeys []types.SSHKey
if opts.ssh != "" {
id, path, found := strings.Cut(opts.ssh, "=")
if !found && id != "default" {
return api.BuildOptions{}, fmt.Errorf("invalid ssh key %q", opts.ssh)
}
SSHKeys = append(SSHKeys, types.SSHKey{
ID: id,
Path: path,
})
}
builderName := opts.builder
if builderName == "" {
builderName = os.Getenv("BUILDX_BUILDER")
}
uiMode := display.Mode
if uiMode == display.ModeJSON {
uiMode = "rawjson"
}
return api.BuildOptions{
Pull: opts.pull,View on GitHub (pinned to ddc4b044b6)
Solutions
- Use the ID=PATH form: `--ssh mykey=/home/me/.ssh/id_rsa`
- Or use `--ssh default` to forward the SSH agent without naming a key
- In scripts, build the flag as `--ssh "id=$KEY_PATH"` so the '=' is always present
Example fix
# before docker compose build --ssh /home/me/.ssh/id_rsa # after docker compose build --ssh default=/home/me/.ssh/id_rsa
Defensive patterns
Strategy: validation
Validate before calling
# normalize --ssh before invoking compose
ssh_flag() {
case "$1" in
default) echo "--ssh default";;
*=*) echo "--ssh $1";;
*) echo "--ssh default=$1";;
esac
}
docker compose build $(ssh_flag "$SSH_ARG") Prevention
- Remember the grammar: `default` or `id=path`, nothing else
- Quote the whole flag so the '=' survives shell splitting
When it happens
Trigger: `docker compose build --ssh mykey` (missing =/path), or `--ssh default=/path` is fine but `--ssh path` alone (a bare path with no ID) fails.
Common situations: Users assuming --ssh takes just a path like some other tools; quoting mistakes that swallow the '='; CI scripts templating --ssh "$SSH_KEY" where the variable holds only a path.
Related errors
- --build and --no-build are incompatible
- --build and --no-build are incompatible
- --no-build and --watch are incompatible
- the classic builder doesn't support SSH keys, set DOCKER_BUI
- cannot specify DEPRECATED "--no-ansi" and "--ansi". Please u
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/5dd19dfe48794e93.
Report an issue: GitHub.