Hub: Fatal: Could not read Username for "https://github.com", No such device or address

Created on 10 Jan 2018  ·  8Comments  ·  Source: github/hub

Hello! :octocat:

Today I was doing the setup of a git automation inside a Docker container using hub and I ran into something that seems a bug.

Authentication method

Since the problem is related to an authentication problem let me give you some context before to talk about the error I have encountered.
In order to perform all the operations, I was using a personal token as mentioned in hub's man page

The part of the script that was configuring hub was looking like this:

hub config --global hub.protocol https
hub config --global user.email $email
hub config --global user.name $username
export GITHUB_TOKEN=$token

The problem

My automation was trying to perform the following operations on a public repository:

  • clone the repository ✅
  • fork the repository ✅
  • add some changes to the fork ✅
  • push the changes to the fork ❌
  • open a pull request on the original repository ❌

The problem was that the push and the pull-request commands both gave me this (meaningless) error:
fatal: could not read Username for "<a href="https://github.com">https://github.com</a>", No such device or address

After a long struggling, I've then found a solution that seems a bit wired to me.

In order to be able to push on my fork I was needed to change this:

hub remote set-url upstream https://github.com/$owner/$repo.git
hub remote set-url origin https://github.com/$username/$repo.git

to this:

hub remote set-url upstream https://$token:[email protected]/$owner/$repo.git
hub remote set-url origin https://$token:[email protected]/$username/$repo.git

Why the $GITHUB_TOKEN environmental variable isn't enough in this situation?
The $GITHUB_TOKENenv var enables me to create a new repo (forking) on my account but does not give me the possibility to push on the same? Am I missing something?

Info to reproduce the error

Below you can find the "complete" script that lets you reproduce the error:

First (non-working) version of my script (click on Details):

# You must set these variables: $email, $username, $token, $repo, $owner 

hub config --global hub.protocol https
hub config --global user.email $email
hub config --global user.name $username
export GITHUB_TOKEN=$token

# Clones the repo
rm -rf ./$repo/
hub clone $owner/$repo
cd ./$repo/

# Fork the repo
hub fork

# Update remotes
hub remote rename origin upstream
hub remote rename $username origin
hub remote -v
hub pull --all

# Add something to the repo
echo "🌈" > 42
git add 42

# Push on our fork
hub push origin -f
# ^-- The push throws the error

Second (working) version of my script (click on Details):

# You must set these variables: $email, $username, $token, $repo, $owner 

hub config --global hub.protocol https
hub config --global user.email $email
hub config --global user.name $username
export GITHUB_TOKEN=$token

# Clones the repo
rm -rf ./$repo/
hub clone $owner/$repo
cd ./$repo/

# Fork the repo
hub fork

# Update remotes
hub remote rename origin upstream
hub remote rename $username origin
hub remote set-url upstream https://$token:[email protected]/$owner/$repo.git
hub remote set-url origin https://$token:[email protected]/$username/$repo.git
hub remote -v
hub pull --all

# Add something to the repo
echo "🌈" > 42
git add 42

# Push on our fork
hub push origin -f

Example of Dockerfile to run the script (click on Details):

FROM alpine:latest

RUN echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories
RUN apk update

RUN apk add git hub bash

# Copy the script
COPY script.sh .

RUN bash pr.sh



If interested you can find the whole script here.

Thank you!

Most helpful comment

Hi thank you for the incredibly detailed report! ✨ ✨

This is something that is often a cause of confusion for hub users: when doing operations such as hub clone or hub fork … hub push, there are two authentication methods to GitHub in play, and they are in no way related! One may be fine, but the other one can be misconfigured (or vice versa).

  1. The first authentication method is the one git uses for pushing git commits to repos or cloning/fetching from private repos, and is _in no way related or affected by hub_. There are basically two authentication strategies for git operations:

  2. The second authentication method is the one hub uses to access the GitHub API. This is completely separate from git protocol authentication described above, for these reasons:

    • Even if there's an SSH key configured to be used for github.com, it can't be used by hub beause GitHub API can only be accessed over HTTPS.
    • Even if there's a password or Personal Access Token configured in git credential helper for use with HTTPS git remotes, it can't be used by hub in most cases due to the following:

      • Most of the GitHub API cannot be accessed with your actual GitHub password and instead must be accessed with an Oauth token (also known as Personal Access Token);

      • The Personal Access Token configured for cloning/pushing to git repos can't be used for all of the GitHub API operations since they might require permissions outside of the default repo scope that the tokens for git cloning are usually created with.

So you see, when you do hub clone owner/project, both authentication methods kick in: first hub checks the GitHub API, then git uses its own authentication method to fetch the repo. When hub users get an authentication error, they are often confused as to why they are getting it, because they have either sorted out git authentication or hub authentication, but they don't realize they need to configure both.

Ideas how to improve the user-friendliness of this is very welcome! Also see plans for #225.

All 8 comments

Hi thank you for the incredibly detailed report! ✨ ✨

This is something that is often a cause of confusion for hub users: when doing operations such as hub clone or hub fork … hub push, there are two authentication methods to GitHub in play, and they are in no way related! One may be fine, but the other one can be misconfigured (or vice versa).

  1. The first authentication method is the one git uses for pushing git commits to repos or cloning/fetching from private repos, and is _in no way related or affected by hub_. There are basically two authentication strategies for git operations:

  2. The second authentication method is the one hub uses to access the GitHub API. This is completely separate from git protocol authentication described above, for these reasons:

    • Even if there's an SSH key configured to be used for github.com, it can't be used by hub beause GitHub API can only be accessed over HTTPS.
    • Even if there's a password or Personal Access Token configured in git credential helper for use with HTTPS git remotes, it can't be used by hub in most cases due to the following:

      • Most of the GitHub API cannot be accessed with your actual GitHub password and instead must be accessed with an Oauth token (also known as Personal Access Token);

      • The Personal Access Token configured for cloning/pushing to git repos can't be used for all of the GitHub API operations since they might require permissions outside of the default repo scope that the tokens for git cloning are usually created with.

So you see, when you do hub clone owner/project, both authentication methods kick in: first hub checks the GitHub API, then git uses its own authentication method to fetch the repo. When hub users get an authentication error, they are often confused as to why they are getting it, because they have either sorted out git authentication or hub authentication, but they don't realize they need to configure both.

Ideas how to improve the user-friendliness of this is very welcome! Also see plans for #225.

Hi @mislav,
Thank you for the reply!

I think there are a lot of things to improve the user-friendliness, but maybe this issue is not the best place to discuss about.

My impression, is that using hub to achieve some simple operation seems just over-complicated.
For example, I would expect something like this to work:

hub auth $GITHUB_TOKEN      <--- This should take care of all the stuffs related to the auth
hub fork $owner/$repo       <--- This should clone, fork and set remotes correctly
# some edits
hub push       <--- Should work without any type of configs if the token have enough rights.

Anyway let's talk about the auth error:
git should not be transparent while using hub. I mean. Hub should predict misconfigurations instead of letting git fail in strange ways.
I believe that hub should provide the same easy-to-use experience of the GitHub website inside the terminal.

Can you show me what is correct way to setup both hub and git authentications using the Personal Access Token ($GITHUB_TOKEN)?
I did not found any good example.

The correct way to auth with both git and hub:

  1. For git HTTPS auth, you want to configure the credentials helper (this is platform-specific) to store the username/token combo. This is an example how to do it with osxkeychain on Mac OS

  2. For hub, doing export GITHUB_TOKEN=$token and configuring hub to always use HTTPS is enough: git config --global hub.protocol https.

What about adding those information somewhere inside the hub's documentation?

Also I believe that the community would appreciate if we add some examples on how to perform some basic operations (authentication, create a fork, open a pull-request, etc) with hub.

In case I would be happy to help.

Adding extra documentation about this would be great, but actually implementing something like hub auth $GITHUB_TOKEN that you've proposed would be even better. See #225 for plans to make a command like that. In the future, hub should have a dedicated auth command, switch to HTTPS protocol by default, and help you set up the git credential helper in case you haven't already.

Any help around implementing this would be welcome!

Closing this in favor of the referenced issue. Authentication should be easier and more friendly once a dedicated command for that is written.

This is something that is often a cause of confusion for hub users:

:beach_umbrella: very true words indeed! :1st_place_medal:

Working in a jenkinsfile, the only thing that worked to be able to push changes back to the origin was this bit of groovy & embedded shell script:

SOURCE_REPO="eclipse/che"
GITHUB_TOKEN="mytokenhere"

sh '''
  export GITHUB_TOKEN=''' + GITHUB_TOKEN + ''' # echo "''' + GITHUB_TOKEN + '''"
  git config --global hub.protocol https
  git remote set-url origin https://\$GITHUB_TOKEN:[email protected]/''' + SOURCE_REPO + '''.git
  git commit ...
  git push
'''

Thanks for the hint!

Was this page helpful?
0 / 5 - 0 ratings