jesseduffield/lazygit · error

Password, passphrase and/or username wrong

Error message

Password, passphrase and/or username wrong

What it means

Returned by FilesController.fetch when a 'git fetch' subprocess fails with exit status 128. The code pattern-matches the error string for 'exit status 128' (git's generic fatal code) and assumes an authentication failure, surfacing Tr.PassUnameWrong ('Password, passphrase and/or username wrong'). Because 128 covers any fatal git error, the message is a heuristic, not a diagnosis: the real cause (often remote auth) is swallowed and only visible in lazygit's command log.

Source

Thrown at pkg/gui/controllers/files_controller.go:1543

		},
		AllowEmptyInput: true,
	})

	return nil
}

func (self *FilesController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
	return self.EnterFile(types.OnFocusOpts{ClickedWindowName: "main", ClickedViewLineIdx: opts.Y})
}

func (self *FilesController) fetch() error {
	fetchGeneration := self.c.State().GetRepoGeneration()
	return self.c.WithWaitingStatus(self.c.Tr.FetchingStatus, func(task gocui.Task) error {
		self.c.LogAction("Fetch")
		err := self.c.Git().Sync.Fetch(task)

		if err != nil && strings.Contains(err.Error(), "exit status 128") {
			return errors.New(self.c.Tr.PassUnameWrong)
		}

		return self.c.Helpers().BranchesHelper.PostFetchRefresh(err, false, fetchGeneration)
	})
}

// Couldn't think of a better term than 'normalised'. Alas.
// The idea is that when you select a range of nodes, you will often have both
// a node and its parent node selected. If we are trying to discard changes to the
// selected nodes, we'll get an error if we try to discard the child after the parent.
// So we just need to filter out any nodes from the selection that are descendants
// of other nodes
func normalisedSelectedNodes(selectedNodes []*filetree.FileNode) []*filetree.FileNode {
	return lo.Filter(selectedNodes, func(node *filetree.FileNode, _ int) bool {
		return !isDescendentOfSelectedNodes(node, selectedNodes)
	})
}

View on GitHub (pinned to c477a2959b)

Solutions

  1. Run the same fetch outside lazygit (git fetch -v) to see the real stderr that lazygit discarded.
  2. For HTTPS: verify/update credentials via your credential helper (e.g. git credential reject, or update the PAT).
  3. For SSH: run ssh -T git@host to test auth, ensure the key is in ssh-agent (ssh-add) and GIT_SSH_COMMAND points at the right key.
  4. Check the remote URL with git remote -v for typos or wrong scheme.
  5. Confirm this is really auth and not another fatal error; exit 128 alone does not prove wrong credentials.

Example fix

// before (heuristic that mislabels any exit-128 fetch failure):
if err != nil && strings.Contains(err.Error(), "exit status 128") {
    return errors.New(self.c.Tr.PassUnameWrong)
}

// after (surface the underlying error, annotate with the auth hint):
if err != nil {
    if strings.Contains(err.Error(), "exit status 128") {
        return fmt.Errorf("%w: %s", err, self.c.Tr.PassUnameWrong)
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before relying on the message, verify auth yourself:
// out, err := exec.Command("git", "fetch", "--dry-run").CombinedOutput()
// inspect out for 'Authentication failed' / 'Permission denied'

Try / catch

if err := controller.fetch(); err != nil {
    if err.Error() == c.Tr.PassUnameWrong {
        // treat as auth failure, but re-run `git fetch -v` externally for the real stderr
    }
}

Prevention

When it happens

Trigger: Pressing the fetch keybinding (default 'f') in the Files panel while the remote rejects credentials: wrong HTTPS password, expired PAT, missing/locked SSH key, or a passphrase prompt that cannot be answered in lazygit's headless subprocess. Also fires for unrelated fatal fetch errors (bad URL, DNS failure, proxy error) since the check only tests the exit code.

Common situations: Expired GitHub/GitLab personal access token; SSH key not added to ssh-agent so authentication fails non-interactively; credential helper misconfigured or missing; typo'd remote URL; corporate proxy blocking the remote. Common right after credential rotation or on a new machine without configured keys.

Related errors


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/82a6f21c40c694d9. Report an issue: GitHub.