Composer: Failed to Clone - Git Authentication Failed in CI
Composer falls back to cloning a package from its Git source when no dist archive is available or for dev- branches. In CI, a private clone fails with "Authentication failed" because the runner has no Git credentials for the host.
What this error means
Composer prints "Failed to clone ... via https/ssh protocols, aborting" with "fatal: Authentication failed for 'https://...'". The same install works locally where Git credentials or an SSH key exist.
- Syncing acme/internal (dev-main) into cache
Failed to clone https://github.com/acme/internal.git, try running with
'--verbose' to debug.
fatal: Authentication failed for 'https://github.com/acme/internal.git/'Common causes
No Git credentials for the private host in CI
The runner has no token or SSH key for the host, so the clone cannot authenticate and Composer cannot prompt non-interactively.
A dev/source install forces a clone
dev- constraints or --prefer-source make Composer clone instead of downloading a dist zip, requiring Git auth it does not otherwise need.
How to fix it
Provide an OAuth token for HTTPS clones
Configure a token Composer uses for the host before installing.
composer config --global --auth github-oauth.github.com "\$GH_TOKEN"
composer install --no-interactionUse an SSH deploy key and ssh URLs
eval "\$(ssh-agent -s)"
ssh-add - <<< "\$DEPLOY_KEY"
# composer.json
# "repositories": [{ "type": "vcs", "url": "git@github.com:acme/internal.git" }]Prefer dist to avoid clones where possible
- Use
--prefer-distso Composer downloads archives instead of cloning. - Verify access with
git ls-remoteusing the same credential. - Confirm the credential host matches the repository URL scheme.
How to prevent it
- Inject a least-privilege token or deploy key into CI for private Git sources.
- Prefer
--prefer-distso most installs need no Git auth. - Match the repository URL scheme (https vs ssh) to the credential provided.