Azure DevOps の「fatal: could not read Username for 'https://dev.azure.com'」
git がそのリクエストの認証情報を持っておらず、聞こうとしましたが、パイプラインには答える人がいません。トークンを送って断られる「Authentication failed」とは違い、ここではトークンがまったく送られていません。
見え方
fatal: could not read Username for 'https://dev.azure.com': terminal prompts disabled
最後のコロンのあとは git の起動のしかたで変わります。エージェントが GIT_TERMINAL_PROMPT=0 にしていれば「terminal prompts disabled」、端末が無ければ「No such device or address」です。メッセージの URL に組織・プロジェクト・リポジトリまで入ることもあります。
1. checkout のステップがスクリプトにトークンを残していない
checkout のステップは、パイプラインのトークンで取得したあと、そのトークンを消します。YAML のリファレンスには、persistCredentials を true にすると最初の取得のあとも OAuth トークンを Git の設定に残す、既定では残さない、とあります。なので、スクリプトの中のあとの git fetch・git pull・git push は送るものがありません。roseout のパイプラインはこれで失敗し、全履歴を取る checkout にこの1行を足して直りました(roseout #4259):
steps: - checkout: self persistCredentials: true
push するには、トークンに書き込みの権限も要ります。Project settings → Repositories → Security で、<プロジェクト名> Build Service (<組織>) に Contribute を、スクリプトが作るなら Create branch や Create tag も許可します。これが無いと、このメッセージでなく TF401027 で断られます。
別のリポジトリには、Microsoft のドキュメントのとおり、URL にトークンを書かずヘッダーで送ります:
git clone -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" <clone URL>
トークンがそのリポジトリに届かないときは、ユーザー名を聞かれるのでなく、たいてい TF401019 になります。
2. 部分クローンが、トークンなしで中身を取りに行く
fetchFilter: blob:none だと、git はファイルの中身をあとで、コマンドが必要としたときに取りに行きます。エージェントはヘッダーを一部の git コマンドにしか渡していません。azure-pipelines-agent #5624 では、既存のワークスペースでエージェントが走らせる片付けが失敗しています:
fatal: could not read Username for 'https://dev.azure.com/<org>/<project>/_git/<repo>': terminal prompts disabled fatal: could not fetch 5f336811b12b22db0d8b76a5b1e5bf42622e77a5 from promisor remote ##[error]Git sparse checkout disable failed with exit code: 128
- よくあるきっかけ(直しの提案 azure-pipelines-agent #5701・未マージより):ジョブ A が
fetchFilter: blob:noneとsparseCheckoutDirectoriesでチェックアウトし、ジョブ B が同じワークスペースで同じリポジトリをそれなしでチェックアウトすると、B が A の sparse checkout を戻すところで失敗します。 - 同じ issue によると、変数
ADD_FORCE_CREDENTIALS_TO_GIT_CHECKOUT_ENHANCED: trueはチェックアウトそのものには効きますが、その片付けには効きません。 - 起きるのは、ワークスペースを使い回すときです。セルフホストのエージェントと、ワークスペースを残す Managed DevOps Pools です。Microsoft がホストするエージェントは、ジョブごとに空のワークスペースで始まります。
- 直しが出るまでは、ワークスペースを新しくすれば片付けが走りません。失敗するジョブに
workspace: clean: allを付けると、チェックアウトの前に古いクローンを消します。
3. URL のトークンが、curl のセキュリティ更新のあとで捨てられる
すぐ上の行が warning: redirecting to なら、git はトークンを持っていたのに捨てています。curl の CVE-2026-94266 の修正が2026年10月に Ubuntu の curl の更新で入り、2.56.0 までの git はリダイレクトされたと思い込んで、認証情報の無い URL からやり直します(Ubuntu のバグ 2171054)。当たるのは、$(System.AccessToken) や個人用アクセス トークンをクローンの URL に書くスクリプトです。runner-images #15014 には、Microsoft がホストする Ubuntu のエージェントがイメージ 20261018.339.1 で失敗し、20261012.334.1 では通ったという報告があります。イメージは GitHub Actions と共通です。上のヘッダーで送る形に変えます。詳しい経緯とバージョンは、同じメッセージの GitHub Actions のページにあります。
自分の PC で出たら
git が保存された認証情報を見つけられず、入力欄も開けませんでした。たとえば Git Credential Manager の無い IDE の中の端末です。Git Credential Manager で一度サインインするか、使っている認証情報ヘルパーに個人用アクセス トークンを保存します。保存したトークンが断られる場合は、このメッセージでなく「Authentication failed」になります。
IntelliJ IDEA と Rider で Azure DevOps のプルリクエストを見るなら
Azure DevOps Pull Requests は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。REST API には、git とは別に IDE のパスワード保管庫に置いた自分の個人用アクセス トークンか、Azure CLI でサインインします。受信箱は無料、投票・コメント・完了は Pro(月 US$1・30日間の無料試用つき)です。画面は日本語です。
Azure DevOps は Microsoft Corporation の商標、IntelliJ IDEA と Rider は JetBrains s.r.o. の商標です。このページは Microsoft・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:「fatal: Authentication failed for 'https://dev.azure.com/…'」 · 「TF401027: You need the Git 'GenericContribute' permission」 · 「TF401019: The Git repository … does not exist」 · English