Cause 1: Expired Service Principal Secret (the most common)
What's actually happening here is that your pipeline uses a service connection backed by a service principal, and that principal's secret has an expiration date. When the secret expires, Azure DevOps can't authenticate to Azure DevOps itself (if you're using a PAT) or to the Git repo via OAuth. The error shows up as TF401019 even though the repo definitely exists and your permissions look fine.
This shows up most often on Monday mornings after a weekend, or right after a quarterly secret rotation that someone forgot to propagate to the service connection. I've seen it break a release pipeline that worked Friday night and failed Saturday at 2 AM.
The fix
- Go to Project Settings > Service connections.
- Find the connection your pipeline uses (usually named something like
azure-devops-sp). - Click Edit, then Update Service Principal.
- Re-enter the client secret or upload a new one. If you don't have the secret, regenerate it in the Azure portal under App registrations.
- Save and run the pipeline again.
The reason step 4 works is that updating the secret refreshes the OAuth token cache Azure DevOps holds. Without that, even a valid secret won't be picked up until the cache expires, which can take up to an hour.
If you're using a PAT instead of a service principal, the same logic applies—PATs expire, and when they do, you get the exact same TF401019. Check the expiration date on the PAT and renew it.
Cause 2: Wrong Repository Name or Path in the YAML
The second most common trigger is a typo in the repository field of your pipeline YAML. This might sound dumb, but I've debugged this for a colleague who had repos/MyApp instead of MyApp, and the error message is identical because Azure DevOps treats a malformed repository reference as a permission issue rather than a validation error.
This typically happens after someone renames a repo in Azure DevOps but forgets to update the pipeline YAML. The error appears right after the rename, and the fix is trivial.
The fix
- Open your pipeline YAML and look for the
resourcesblock or thecheckoutstep. - Verify the repository name matches the exact name in Azure DevOps (case-sensitive).
- If you're using a self-hosted agent, also check the
selfrepository definition—it might point to an old clone path. - Correct the name and commit.
Also check if you're referencing a repo from a different project. Cross-project references need the project field set, like repository: MyProject/MyRepo. Missing that causes the same error.
Cause 3: Insufficient Permissions on the Repo
The third cause is that the service principal or the build identity doesn't have read access to the repository. This happens when a repo is created in a different project than the pipeline, or when you've restricted branch permissions to specific users or groups.
I saw this once when a security admin locked down the main branch to only allow PRs, and the pipeline's build service account wasn't in the allowed list. The pipeline failed with TF401019 on every commit, but only on the main branch.
The fix
- Go to Project Settings > Repositories > select the repo.
- Click Security and find the Build Service account (e.g.,
ProjectName Build Service (orgname)). - Grant it at least Read permission. For pipelines that need to push tags or branches, also grant Contribute.
- If the repo is in another project, you need to add the build service from the pipeline's project to that repo's permissions.
Branch policies can also interfere. If you have a branch policy that requires a specific reviewer group, the build service might be blocked. Check Branch Policies for the branch you're checking out.
Quick-Reference Summary
| Cause | Symptom | Fix |
|---|---|---|
| Expired service principal secret | Pipeline worked before, now fails with TF401019 | Update the service connection's secret or PAT |
| Wrong repository name/path | Fails right after repo rename or YAML edit | Correct the repository reference in YAML |
| Missing permissions | Fails only on certain branches or after security changes | Grant build service Read/Contribute on repo |
One last thing: if none of these fix it, check the agent's local Git config. On self-hosted agents, a stale credential manager can cause TF401019 even when everything server-side is fine. Run git config --list on the agent and look for wrong URLs in remote.origin.url.