Ошибка git@gitlab.com: Permission denied (publickey). fatal: Could not read from remote repository значит одно: GitLab не принял ваш SSH-ключ. Репозиторий при этом может существовать, доступ по HTTPS — работать, а git fetch/git push по SSH — нет. Ниже рабочий чеклист для Windows, macOS и Linux без «магии».
Что проверить за 2 минуты
- Вы действительно ходите по SSH, а не по HTTPS: remote вида
git@gitlab.com:group/project.git. - Ключ есть локально: файлы
~/.ssh/id_ed25519+id_ed25519.pub(илиid_rsa/id_rsa.pub). - Публичный ключ добавлен в GitLab: Preferences → SSH Keys (или ключ деплоя в настройках проекта).
- ssh-agent знает приватный ключ (особенно на Windows и при нескольких ключах).
1. Создать ключ (если ещё нет)
Предпочтительный алгоритм сейчас — Ed25519:
ssh-keygen -t ed25519 -C "you@example.com" -f ~/.ssh/id_ed25519
Парольную фразу лучше задать. На старых системах, где Ed25519 не принимают, используйте RSA 4096:
ssh-keygen -t rsa -b 4096 -C "you@example.com" -f ~/.ssh/id_rsa
В GitLab вставляют только содержимое .pub. Приватный ключ никуда не копируют.
2. Добавить ключ в GitLab
# Linux / macOS
cat ~/.ssh/id_ed25519.pub
# Windows (Git Bash / PowerShell)
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub
Откройте https://gitlab.com/-/user_settings/ssh_keys (self-hosted — свой URL), вставьте ключ целиком, начиная с ssh-ed25519 или ssh-rsa, сохраните. Для CI/сервера чаще используют Deploy Key в настройках конкретного репозитория — он не равен личному ключу аккаунта.
3. Проверить соединение
ssh -T git@gitlab.com
Ожидаемый ответ вроде Welcome to GitLab, @username!. Если снова Permission denied — смотрите подробно:
ssh -vT git@gitlab.com
В логе ищите строки Offering public key и Authentication succeeded. Если ключ не предлагается — проблема в agent/config, а не в GitLab.
4. ssh-agent и несколько ключей
На Linux/macOS:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
На Windows с OpenSSH-сервисом agent обычно уже есть; в Git Bash:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Если ключей несколько (работа / личка / self-hosted), зафиксируйте Host в ~/.ssh/config:
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host gitlab.company.local
HostName gitlab.company.local
User git
IdentityFile ~/.ssh/id_company
IdentitiesOnly yes
IdentitiesOnly yes критичен: иначе ssh перебирает слишком много ключей, и сервер может ответить denied до нужного.
5. Частые причины на практике
- Ключ добавлен не в тот аккаунт — клон под другим пользователем GitLab.
- Вставлен приватный ключ вместо
.pub— GitLab отвергнет. - Ключ истёк / отозван — в UI SSH Keys проверьте срок и список.
- Self-hosted на нестандартном порту — в config укажите
Port 2222. - Корпоративный прокси / firewall режет 22/tcp — иногда дают SSH на 443; уточните у админов.
- Wrong remote URL — опечатка в group/project; тогда после успешного SSH будет уже «repository not found».
- Права на файлы ключа слишком открытые (Linux):
chmod 600 ~/.ssh/id_ed25519,chmod 700 ~/.ssh.
6. Временный обход через HTTPS
Если нужно срочно пушнуть, можно переключить remote на HTTPS и использовать personal access token вместо пароля:
git remote -v
git remote set-url origin https://gitlab.com/group/project.git
git push
Это обход, не замена SSH на серверах CI и на BitrixVM, где ключ удобнее токена в интерактиве.
Вывод
Permission denied (publickey) почти никогда не лечится «переустановкой Git». Цепочка одна: локальный ключ → agent/config → публичный ключ в GitLab → ssh -T успешен → remote на git@.... Пройдите её сверху вниз с ssh -vT, и ошибка уходит за один проход.
