could not resolve remote "origin": none of the git remotes configured for this repository correspond to the `GH_HOST` environment variable.
Describe the bug
When using GH_HOST, GH_REPO, and GH_ENTERPRISE_TOKEN in conjunction with gh pr create, it started failing about a week ago for us, and we can't reproduce as a human (even with a token) or determine any glaring differences between the CI/CD and local invocations of the same tool, nor even with any version bumps since the last working version (~even if we downgrade to 2.70.0, it still fails now~ 2.70.0 still works actually).
could not resolve remote "origin": none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
Some of the settings/troubleshooting attempts
GH_HOST=our.enterprise.host
GH_REPO=out.enterprise.host/ourorg/ourrepo
GH_ENTERPRISE_TOKEN=<set to something>
GH_DEBUG=true
00:00:45 + git remote -v
00:00:45 origin [email protected]:ourorg/ourrepo (fetch)
00:00:45 origin [email protected]:ourorg/ourrepo (push)
00:00:45 + git version
00:00:45 git version 2.43.5
00:00:45 + gh version
00:00:45 gh version 2.71.2 (2025-04-24)
00:00:45 + git config --get-regexp '^branch\.autoupdate/20250428-183455\.(remote|merge|pushremote|gh-merge-base)$'
00:00:45 branch.autoupdate/20250428-183455.remote origin
00:00:45 branch.autoupdate/20250428-183455.merge refs/heads/autoupdate/20250428-183455
00:00:45 + git rev-parse --symbolic-full-name 'autoupdate/20250428-183455@{push}'
00:00:45 refs/remotes/origin/autoupdate/20250428-183455
and invocation
00:00:45 + gh pr create --label autoupdate-server_admap --title '[autoupdate][20250428-183455] Update files from source folder' --body 'This PR is a result of script, which auto update files from the source directory.'
00:00:45 [git remote -v]
00:00:45 [git config --get-regexp ^remote\..*\.gh-resolved$]
00:00:45 * Request at 2025-04-28 18:34:59.675488605 +0000 UTC m=+0.085715954
00:00:45 * Request to https://our.enterprise.host/api/graphql
00:00:46 * Request took 245.740739ms
00:00:46 [git status --porcelain]
00:00:46 [git symbolic-ref --quiet HEAD]
00:00:46 [git config --get-regexp ^branch\.autoupdate/20250428-183455\.(remote|merge|pushremote|gh-merge-base)$]
00:00:46 [git rev-parse --symbolic-full-name autoupdate/20250428-183455@{push}]
00:00:46 could not resolve remote "origin": none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
Affected version
Please run gh version and paste the output below.
gh version 2.71.2 (2025-04-24)
Steps to reproduce the behavior
- Have an enterprise server
- Set the GH_HOST, GH_REPO, GH_ENTERPRISE_TOKEN appropriately
- Have an origin with ssh-formatted location (not quite URL but git@ style)
Expected vs actual behavior
A PR should be created (and was up until a week ago); the error regarding inability to find the origin is output and a failure rc is returned.
Logs
See invocation above
Hmmm sorry for the inconvenience. If possible can you provide the debug logs with 2.70.0 as well? Would just like to double check something.
Actually… I think we didn't actually try with 2.70.0 - there were two cases where the downgrade was done and the place we were eyeballing didn't have the downgrade… we're trying it again now… if that fixes things, I'll let you know!
v2.70.0 actually DOES work afterall, still.
00:01:02 + gh pr create --label autoupdate-deals --title '[autoupdate][deals][20250428-232318] Update files from source folder' --body 'This PR is a result of script, which auto update files from the source directory.'
00:01:02 [git remote -v]
00:01:02 [git config --get-regexp ^remote\..*\.gh-resolved$]
00:01:02 * Request at 2025-04-28 23:23:22.060837195 +0000 UTC m=+0.072287632
00:01:02 * Request to https://our.enterprise.host/api/graphql
00:01:02 * Request took 227.920413ms
00:01:02 [git symbolic-ref --quiet HEAD]
00:01:02 [git status --porcelain]
00:01:02 [git config --get-regexp ^branch\.autoupdate/20250428-232318\.(remote|merge|pushremote|gh-merge-base)$]
00:01:02 [git show-ref --verify -- HEAD refs/remotes/origin/autoupdate/20250428-232318]
00:01:02 * Request at 2025-04-28 23:23:22.314543122 +0000 UTC m=+0.325993562
00:01:02 * Request to https://our.enterprise.host/api/graphql
00:01:02 * Request took 148.505962ms
00:01:02 * Request at 2025-04-28 23:23:22.46389135 +0000 UTC m=+0.475341806
00:01:02 * Request to https://our.enterprise.host/api/graphql
00:01:03 * Request took 126.888572ms
00:01:03 * Request at 2025-04-28 23:23:22.59096085 +0000 UTC m=+0.602411290
00:01:03 * Request to https://our.enterprise.host/api/graphql
00:01:03 * Request took 558.349206ms
00:01:03 * Request at 2025-04-28 23:23:23.149547271 +0000 UTC m=+1.160997715
00:01:03 * Request to https://our.enterprise.host/api/graphql
00:01:04 * Request took 473.630369ms
00:01:04 https://our.enterprise.host/ourorg/ourrepo/pull/1329
Makes sense that the problem would be introduced in 2.71.0 with all the changes we made around respecting git config on pr create. Thanks for the extra information!
So, the only explanation I have for this right now is that we were previously suppressing an error:
https://github.com/cli/cli/blob/e1387821af26cfcbb562714bf695be17a3db9a43/pkg/cmd/pr/create/create.go#L966
And the same codepath that was called here is now called later with the error unsuppressed:
https://github.com/cli/cli/blob/e1387821af26cfcbb562714bf695be17a3db9a43/pkg/cmd/pr/shared/find_refs_resolution.go#L260
However, I cannot reproduce your error with a valid setup:
➜ test git:(feature) gh version
gh version 2.71.2 (2025-04-24)
https://github.com/cli/cli/releases/tag/v2.71.2
➜ test git:(feature) echo $GH_HOST
ghe.io
➜ test git:(feature) echo $GH_REPO
ghe.io/williammartin/test
➜ test git:(feature) echo $GH_ENTERPRISE_TOKEN
gho_****************************
➜ test git:(feature) git remote -v
origin [email protected]:williammartin/test.git (fetch)
origin [email protected]:williammartin/test.git (push)
➜ test git:(feature) GH_DEBUG=1 gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-04-29 10:31:45.050698 +0200 CEST m=+0.126742585
* Request to https://ghe.io/api/graphql
* Request took 599.400333ms
[git status --porcelain]
[git symbolic-ref --quiet HEAD]
[git config --get-regexp ^branch\.feature\.(remote|merge|pushremote|gh-merge-base)$]
[git rev-parse --symbolic-full-name feature@{push}]
[git show-ref --verify -- HEAD refs/remotes/origin/feature]
⣾* Request at 2025-04-29 10:31:45.705733 +0200 CEST m=+0.781773793
* Request to https://ghe.io/api/graphql
⢿* Request took 413.290583ms
Creating pull request for feature into main in williammartin/test
⣾* Request at 2025-04-29 10:31:46.125649 +0200 CEST m=+1.201688543
* Request to https://ghe.io/api/graphql
⣯* Request took 751.386625ms
https://ghe.io/williammartin/test/pull/11
The only way I can reproduce it is if I misconfigure GH_HOST:
➜ test git:(feature) echo $GH_HOST
ghe.ios
Then v2.71.0 fails where v2.70.0 passes:
➜ test git:(feature) GH_DEBUG=1 gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-04-29 10:18:06.631162 +0200 CEST m=+0.139859959
* Request to https://ghe.io/api/graphql
* Request took 487.029459ms
[git status --porcelain]
[git symbolic-ref --quiet HEAD]
[git config --get-regexp ^branch\.feature\.(remote|merge|pushremote|gh-merge-base)$]
[git rev-parse --symbolic-full-name feature@{push}]
could not resolve remote "origin": none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
➜ test git:(feature) GH_DEBUG=1 ~/workspace/cli/bin/gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-04-29 10:18:22.991411 +0200 CEST m=+0.097882043
* Request to https://ghe.io/api/graphql
* Request took 437.762208ms
[git symbolic-ref --quiet HEAD]
[git status --porcelain]
[git config --get-regexp ^branch\.feature\.(remote|merge|pushremote|gh-merge-base)$] [git show-ref --verify -- HEAD refs/remotes/origin/feature]
* Request at 2025-04-29 10:18:23.48337 +0200 CEST m=+0.589838793
* Request to https://ghe.io/api/graphql ⣻* Request took 305.86ms
Creating pull request for feature into main in williammartin/test
⣾* Request at 2025-04-29 10:18:23.793544 +0200 CEST m=+0.900011668
* Request to https://ghe.io/api/graphql
⡿* Request took 607.150375ms
https://ghe.io/williammartin/test/pull/8
Or, if I misconfigure the git remote:
➜ test git:(feature) echo $GH_HOST
ghe.io
➜ test git:(feature) git remote -v
origin [email protected]:williammartin/test.git (fetch)
origin [email protected]:williammartin/test.git (push)
➜ test git:(feature) GH_DEBUG=1 gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-04-29 10:23:47.706454 +0200 CEST m=+0.072512876
* Request to https://ghe.io/api/graphql
* Request took 379.052667ms
[git status --porcelain]
[git symbolic-ref --quiet HEAD]
[git config --get-regexp ^branch\.feature\.(remote|merge|pushremote|gh-merge-base)$]
[git rev-parse --symbolic-full-name feature@{push}]
could not resolve remote "origin": none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
➜ test git:(feature) GH_DEBUG=1 ~/workspace/cli/bin/gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
* Request at 2025-04-29 10:23:57.933781 +0200 CEST m=+0.072119417
* Request to https://ghe.io/api/graphql
* Request took 343.252959ms
[git symbolic-ref --quiet HEAD]
[git status --porcelain]
[git config --get-regexp ^branch\.feature\.(remote|merge|pushremote|gh-merge-base)$]
[git show-ref --verify -- HEAD refs/remotes/origin/feature]
⣾* Request at 2025-04-29 10:23:58.328791 +0200 CEST m=+0.467128001
* Request to https://ghe.io/api/graphql
⣻* Request took 295.429ms
Creating pull request for feature into main in williammartin/test
⣾* Request at 2025-04-29 10:23:58.629306 +0200 CEST m=+0.767641459
* Request to https://ghe.io/api/graphql
⡿* Request took 534.9275ms
https://ghe.io/williammartin/test/pull/10
This is strange behaviour but works because the value of GH_REPO is used to determine the host to target for API requests, and because the branch is already pushed, there's no need to use the git remote.
➜ test git:(feature) unset GH_REPO
➜ test git:(feature) GH_DEBUG=1 ~/workspace/cli/bin/gh pr create --title test --body test
[git remote -v]
[git config --get-regexp ^remote\..*\.gh-resolved$]
none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
It's highly likely that I'm missing something here, but can you please double check GH_REPO, GH_HOST and git remote -v configuration. If you don't think you can share these publicly but are willing to share with me you can email me at my handle @github.com.
hi - sent an email with fuller logs… if you have any public slack/irc/other connectivity to chat please LMK if you have patience to troubleshoot closer to "live"
Investigation Summary
The error:
could not resolve remote "origin": none of the git remotes configured for this repository correspond to the GH_HOST environment variable. Try adding a matching remote or unsetting the variable
Comes from our code that "resolves remotes" which is a process of:
- Collecting git remotes in the current working directory
- Collecting known hosts (e.g. those in
hosts.ymlorGH_HOSTenv var, orgithub.com) - Using the remote URL to construct a repo struct with a host that has undergone SSH translation (more on this below)
- Filtering the git remotes to retain only those with a repo host that match a subset of known hosts
In the case of a user providing the GH_HOST env var, we expect to only retain the git remotes for those with a repo host that matches exactly the value of `GH_HOST.
SSH Translation
SSH Translation is the process of taking a git remote that is an SSH URL (e.g. [email protected]:cli/cli) and asking ssh whether the host (github.com) is being mapped to some other hostname. This mapping usually lives in ~/.ssh/config and looks like:
Host host1
HostName host1.example.com
It's important that gh does this translation in order to send API requests to the real host, for example, when creating a pull request.
Problem
If a user does not have a host in the hosts.yml, the only way they can indicate the presence of a known host to gh is via the GH_HOST environment variable. This GH_HOST environment variable is used by commands that don't have a base repo to provide the host (e.g. gh repo list) to determine the API endpoint. Without this environment variable set, remotes for an expected host will be filtered out as per the bullet list above and also as per the bulleted list above, it is expected that the value of GH_HOST exactly matches the repo's hostname, after SSH translation.
So given I want to create a PR in my enterprise server that doesn't exist in hosts.yml, a user must pass GH_HOST
GH_HOST=myghes.com gh pr create --title title --body body
However if my enterprise setup also has a hostname mapping to force ssh requests to go through a proxy:
Host myghes.com
HostName ssh-proxy.myghes.com
Then after SSH translation myghes.com will not match ssh-proxy.myghes.com and no remotes will be retained.
Evidence
In https://github.com/cli/cli/compare/trunk...wm/debug-gh-host-ssh-translate, you will find a commit with acceptance test that demonstrates this behaviour (requires some manual patching of go-gh to avoid writing to a real SSH config), and a commit with a series of debug logs sprinkled throughout.
Here is the output of the debug logs for this test:
> exec gh pr create --title 'Feature Title' --body 'Feature Body'
[stdout]
*** Starting Resolver
Git Remotes (1)
Name: origin
FetchURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
PushURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
*** Starting TranslateRemotes
Translating: origin
Fetch URL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
Translated Fetch URL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
*** Ending TranslateRemotes
Resolved Remotes (1)
Name: origin
FetchURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
PushURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
Repo: &ghrepo.ghRepo{owner:"gh-acceptance-testing", name:"pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw", hostname:"example.com"}
*** Starting FilterByHosts
Hosts: (1)
Host: github.com
Remotes: (1)
Name: origin
FetchURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
PushURL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
Repo: &ghrepo.ghRepo{owner:"gh-acceptance-testing", name:"pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw", hostname:"example.com"}
Comparing example.com to github.com
No match example.com to github.com
Retained Remotes: (0)
*** Ending FilterByHosts
Filtering by default host: github.com
*** Starting FilterByHosts
Hosts: (1)
Host: github.com
Remotes: (0)
Retained Remotes: (0)
*** Ending FilterByHosts
*** Ending Resolver
*** Starting Resolver
*** Ending Resolver
We can see the translation of our FetchURL
*** Starting TranslateRemotes
Translating: origin
Fetch URL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
Translated Fetch URL: ssh://[email protected]/gh-acceptance-testing/pr_create_ssh_hostname_rewrite_and_gh_host-rhnQEabRYw.git
*** Ending TranslateRemotes
And that the later comparison uses the translated URL:
Comparing example.com to github.com
No match example.com to github.com
Why didn't this fail before?
Alluded to in https://github.com/cli/cli/issues/10891#issuecomment-2837930924, before v2.71.0 we were suppressing this error in the only place that remotes were resolved during pr create
https://github.com/cli/cli/blob/e1387821af26cfcbb562714bf695be17a3db9a43/pkg/cmd/pr/create/create.go#L960-L971
However, with the changes in v2.71.0, we started calling this function in another location and are not suppressing the error:
https://github.com/cli/cli/blob/e1387821af26cfcbb562714bf695be17a3db9a43/pkg/cmd/pr/shared/find_refs_resolution.go#L255-L262
This may indicate another bug that I need to look into with regards the comment:
// When a repo override value is given, ignore errors when fetching git remotes
// to support using this command outside of git repos.
But that is outside the scope of this investigation.
What do we do next?
Todo, since it's a vacation day here but I wanted to write this up for the team to look at.
If I understand everything above, it seems like the problem is that resolving remotes does not consider the SSH aliasing case below:
https://github.com/cli/cli/blob/d6d82758095eaf6dbe6465edbe5202ec26ba453e/pkg/cmd/factory/remote_resolver.go#L72-L80
Should this line also include the translated version of the hosts when trying to resolve the remotes? If so, does the ordering matter? Should a translated host have higher precedence?
Well the latest debugging with @williammartin has shown that
- We have a Host directive in the
$HOME/.ssh/config - If we set GH_HOST to that instead of the name used in the GH_REPO (first path) it seems to work.
I don't like needing to know how my ssh is configured to make the tool work, but would be ok with some flag or env var to disable the ssh inspection if that could be possible in the tool.
I suppose, we could learn about, and provide a yaml file if that would fix the behavior- I think we want/need the REST stuff to go to the named host, even if the ssh stuff (push/pull) goes through the x509 proxy.
Collecting known hosts (e.g. those in hosts.yml or GH_HOST env var, or github.com)
I don't see mention of hosts.yml in the https://cli.github.com/manual/gh_pr_create (don't see any search there either, so clicked around to a few places I thought it might be but came up empty for in-page search for hosts.yml).
I don't see mention of hosts.yml in the https://cli.github.com/manual/gh_pr_create (don't see any search there either, so clicked around to a few places I thought it might be but came up empty for in-page search for hosts.yml).
host.yml is an implementation detail. When a user runs gh auth login the targeted host is persisted along with any other configuration (e.g. chosen git protocol, token if using --insecure-storage).
@scr-oath, one other workaround occurred to me today. If I recall correctly, your workflow is creating a PR from a branch that already exists remotely, before you run gh pr create. If you provided the --head flag with the name of that branch (or owner:branch if it is in a fork) then gh will choose a different code path than the one that results in the error surfacing.
I appreciate this still isn't exactly what you want, but I think it's probably an improvement over setting GH_HOST to the value of the resolved SSH hostname?
Interesting, yes, we do git push before invoking gh pr create… I can try adding that flag to see if it helps… stay tuned; will update this comment.
- Seems to work 👍