Skip to content

Instantly share code, notes, and snippets.

@sodiboo
Created February 21, 2026 21:59
Show Gist options
  • Select an option

  • Save sodiboo/8bcd27b6fa67fce006ffe193df25c49e to your computer and use it in GitHub Desktop.

Select an option

Save sodiboo/8bcd27b6fa67fce006ffe193df25c49e to your computer and use it in GitHub Desktop.
forgejo 11: "Unable to commit-tree in temporary repo" (SSH instance commit signing not supported)
experienced this in forgejo v11.0.10

this issue causes a couple different error messages

when creating a repo with "committer" trust model:

CreatePost: initRepository: initRepoCommit: git commit: exit status 128 - fatal: empty ident name (for <>) not allowed

(log file)

when creating a file with "collaborator" trust model:

Unable to commit-tree in temporary repo: username/reponame Error: exit status 1
Stdout:
Stderr: error: gpg failed to sign the data:
gpg: skipped "/data/ssh/ssh_host_ed25519_key": No secret key
[GNUPG:] INV_SGNR 9 /data/ssh/ssh_host_ed25519_key
[GNUPG:] FAILURE sign 17
gpg: signing failed: No secret key

(red error message in frontend)

in general, "collaborator" trust model causes a more detailed error message. also saw:

Unable to commit-tree in temporary repo: username/reponame Error: exit status 1
Stdout:
Stderr: error: gpg failed to sign the data:
gpg: Note: database_open 134217901 waiting for lock (held by 420) ...
gpg: Note: database_open 134217901 waiting for lock (held by 420) ...
gpg: Note: database_open 134217901 waiting for lock (held by 420) ...
gpg: Note: database_open 134217901 waiting for lock (held by 420) ...
gpg: keydb_search failed: Operation timed out
gpg: skipped "/data/ssh/ssh_host_ed25519_key": No secret key
[GNUPG:] INV_SGNR 0 /data/ssh/ssh_host_ed25519_key
[GNUPG:] FAILURE sign 134250628
gpg: signing failed: No secret key

here, 420 is a placeholder pid. but like, a zombie one? same pid persists after reboot.

the lock error is unrelated but might happen due to this issue if you're restarting your container while trying to perform commits in the web interface?
to fix the error with the lockfile, delete something like /data/gitea/home/.gnupg/pubring.lock (?). filepath may vary. $HOME/.gnupg/*.lock for the forgejo user.

if this lockfile error happens on collaborator trust model, the committer trust model will still only show fatal: empty ident name (for <>) not allowed.


the root cause is that we are using an older/LTS version of forgejo, but trying to use SSH keys for instance commit signing.

[repository.signing]
DEFAULT_TRUST_MODEL = committer
FORMAT = ssh
SIGNING_KEY = /data/ssh/ssh_host_ed25519_key

the forgejo documentation clearly states that FORMAT = ssh means SIGNING_KEY is a path to an ssh key.

however, in the documentation for v11.0 this is not mentioned.

that's because this feature was added in this pull request, which was part of Forgejo v12.0.

so, the FORMAT = ssh is ignored in v11.0, and SIGNING_KEY is interpreted as a GPG Key ID (not a file path!!!!)


forgejo reads this config in SigningKey()

  • SIGNING_KEY = none means to not sign.
  • SIGNING_KEY = default or SIGNING_KEY = "" or unset will use git config --get user.signingkey and git config --get user.gpgsign.
  • else, it returns SIGNING_KEY as the GPG key ID.

this key is passed up through SignCRUDAction()

and passed as -S to git commit-tree in right here

that git option only takes a GPG key ID, not an SSH key path.

as such, GPG looks for a key with identity /data/ssh/ssh_host_ed25519_key. and not a key at that path.

the reason for the much less useful error message if you have the trust model as comitter, is because of this bit. when the trust model is committer, it also adds these headers to the commit metadata:

Co-authored-by: /data/ssh/ssh_host_ed25519_key
Co-committed-by: /data/ssh/ssh_host_ed25519_key

and the thing is, /data/ssh/ssh_host_ed25519_key is technically valid kinda? it's an identity, sure. and it has no email part (which would've come after the display name: <email-goes-inside-angle-brackets@example.com>)

because these additional headers are being passed, git does correctly parse them, validate that their email is not empty. and then because the email is empty, it exits early without invoking gpg. so the error message is much less useful:

git commit: exit status 128 - fatal: empty ident name (for <>) not allowed

solution

either upgrade to forgejo >= v12.0. they support this

or:

remove FORMAT = ssh and SIGNING_KEY = from your config. it will use the forgejo user's default git GPG signing options.

you might end up not signing your instance commits at all if you do that (that is, stuff done through web interface, incl. PR merge commits, will be unsigned). so, make sure to actually like, have a GPG key configured in git.

you can also set SIGNING_KEY = forgejo <forgejo@my.forgejo.instance.example.org>. or any other key id. and make sure to generate an according key that your forgejo user can see.
if you explicitly set this option, that ensures it won't fallback to not signing at all, should your git config tell it not to do so. instead, when the option is set to anything other than "", "none", "default", and it can't find that key, it will fail with an error similar to what is shown above.

to create a GPG key, run gpg --full-generate-key as the forgejo user.

number of hours wasted on this: surprisingly few. only like, three or four i think? hopefully, the next poor soul will find this gist, and waste even less time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment