Ken Muse

Troubleshooting Git Authentication


An interesting question comes up from time to time: how to you troubleshoot issues with Git authentication? Whether you’re dealing with bad credentials or connectivity issues, it’s important to quickly understand why things are not working. Thankfully, there are a few tricks that can help.

Turning on the TRACE

Git has numerous environment variables which can be set to true or 1 (other other values) to enable writing additional detailed messages. These all begin with GIT_TRACE. For example, using setting GIT_TRACE=1 will enable general trace messages, while GIT_TRACE_SETUP will output details about the current working directory, .git directory, and working tree directory. For more detailed messages, the environment variables starting with GIT_TRACE2 can be used.

Want to see a detailed trace? Just add more variables. For example, you could do the following in Bash:

1GIT_TRACE2=1 GIT_TRACE_REFS=1 GIT_TRACE_CURL=1 git pull

These variables make it easier to see what’s happening and to understand how information is being processed by Git. A full list of trace variables can be found in the Git documentation.

Ask and you SSHall receive

If you’re using SSH, then you may want additional visibility to those messages as well. This can be enabled by using the special environment variable, GIT_SSH_COMMAND. This allows you to provide additional flags to the SSH executable (or select a different one) that can be used for troubleshooting. The most common one is -vvv (where each v indicates an additional level of verbosity). This can be combined with other variables. For example:

1GIT_SSH_COMMAND="ssh -vvv" GIT_TRACE2=1 git clone [email protected]/myorg/repo.git

This will provide additional details from both the SSH command and Git.

Finding Your Credentials

Many times, we need to go lower level and understand which credentials are being used. The git credential fill command can help with that. When the command runs, it expects a series of name=value pairs to be provided with details about the connection. Each value should be on a separate line. To indicate there are no additional values, simply press Return/Enter to create an empty line. Git will respond with the user name and password (or token) that will be used for connecting.

For example, to troubleshoot https://github.com/someuser/myrepo.git, type:

1$ git credential fill
2protocol=https
3host=github.com
4path=someuser/murepo.git

Git will respond with similar details, plus two additional fields: username and password. If you run the command with GIT_TRACE=1 or GIT_TRACE2=1, you will see Git resolve the appropriate credential provider and then return the value. If the appropriate credential cannot be identified, then Git will prompt a login to resolve the values. As an example, a session would start like this:

1$ GIT_TRACE2=1 git credential fill
219:35:40.720023 common-main.c:55                  version 2.43.0
319:35:40.720613 common-main.c:56                  start git credential fill
419:35:40.787004 repository.c:143                  worktree /Users/kenmuse/Documents/Code/elastic-machines
519:35:40.787877 git.c:464                         cmd_name credential (credential)
6protocol=https 
7host=github.com
8path=kenmuse/kenmuse.git

And the response from Git looks similar to this (aside from the redacted password):

 119:35:41.953010 run-command.c:726                 child_start[0] 'git credential-osxkeychain get'
 219:35:41.975235 common-main.c:55                  version 2.43.0
 319:35:41.975575 common-main.c:56                  start git credential-osxkeychain get
 419:35:41.976092 git.c:743                         cmd_name _run_dashed_ (credential/_run_dashed_)
 519:35:41.976100 run-command.c:726                 child_start[0] git-credential-osxkeychain get
 619:35:42.024190 run-command.c:979                 child_exit[0] pid:65056 code:0 elapsed:0.048034
 719:35:42.024254 git.c:765                         exit elapsed:0.049974 code:0
 819:35:42.024265 trace2/tr2_tgt_normal.c:127       atexit elapsed:0.049983 code:0
 919:35:42.025102 run-command.c:979                 child_exit[0] pid:65055 code:0 elapsed:0.072085
1019:35:42.652229 run-command.c:726                 child_start[0] '/usr/bin/gh auth git-credential get'
1119:35:42.749989 run-command.c:979                 child_exit[0] pid:66123 code:0 elapsed:0.097763
12protocol=https
13host=github.com
14username=kenmuse
15password=*********

Notice that Git first tries spawning git credential-osxkeychain. This does not provide a response with the requested details, so it then calls gh auth git-credential. This process succeeds in returning the credentials. Depending on your configuration, you may see one or multiple providers in the message chain. Once the credential is retrieved, the process stops.

And if you just want to see a list of your configured credential providers? Run git config --list --show-origin | grep credential. It’s worth mentioning that some environments – such as VS Code or dev containers – may add additional providers. As a result, you may see different results depending on where the command is run.

And that’s all there is to troubleshooting the credentials flow. Being able to trace the data flows and identify the credential providers involved makes its easy to figure out the authentication process. You can also identify where the credential is stored if it needs to be cleared. Hope you had fun diving a bit deeper into the internals of Git!