Upgrade Path

Forgejo 11.0.0 → 16.0.5

30 versions, 5 with breaking changes, 7 with upstream notes or warnings only, 0 required stops

Version by version, oldest first

11.0.1 – 11.0.2: no action items (2 versions)

11.0.3 2025-07-10

Note

Git update fixing CVE-2025-48385

Git vulnerabilities were disclosed 8 July 2025 and require an update of the Git version used by Forgejo to Git v2.43.7, v2.44.4, v2.45.4, v2.46.4, v2.47.3, v2.48.2, v2.49.1, or v2.50.1. The containers of this release include a Git binary that is not vulnerable. If Forgejo was installed using a container, it is enough to upgrade the container to get the latest Git binary.

Security bug fixes are only for Git, there are no security fixes for Forgejo itself in this release.

Wiki permissions manual steps

If collaborators with write access can't edit the wiki, an administrator can now go to the Units settings (<user>/<repo>/settings/units#wiki) and Save the wiki settings (no change is needed) to fix the problem. This is a manual step that will trigger a database update that is currently not possible to automate for Forgejo stable releases.

Full release notes for 11.0.3

11.0.4 – 11.0.16: released after 12.0.0; not on this route

12.0.0 2025-07-17

Breaking

  • Breaking security features
  • PR: remove API authentication methods that uses the URL query. They are disabled by default and this only has an impact if [security].DISABLE_QUERY_AUTH_TOKEN=false is explicitly set. Read more in the v12.0 companion blog post.

Breaking

  • Breaking features
  • PR: The forgejo docs command is deprecated and CLI errors are now displayed on stderr instead of stdout. These breaking changes happened because the package used to parse the command line arguments was upgraded from v2 to v3. A separate project was initiated to re-implement the docs command, but it is not yet production ready.
  • PR: remove the legacy TEST_CONFLICTING_PATCHES_WITH_GIT_APPLY setting

Breaking

  • Breaking bug fixes
  • PR: fail if sha is not provided to the POST /repos/{owner}/{repo}/contents API endpoint. Although it was documented to be required, it was not enforced and clients that do not set the sha will no longer succeed.

Full release notes for 12.0.0

12.0.1 2025-07-25

Note

Insecure authentication methods have been deprecated since 2023. They were removed in v12.0.0 but they were restored in v12.0.1. Certain OAuth2 clients and packages in the Forgejo ecosystem still rely on these methods and it was premature to remove them.

Full release notes for 12.0.1

12.0.2 2025-08-31

Note

Detailed comments on security bug fixes

  • PR (backported): fix: email comments are removed from email addresses When registering with an email account including a comment (e.g. me@example.com (a comment here)), the comment is removed from the email address. It was possible to include an email address in the comment to bypass the block list. For instance if registering with me@evilcorp.com (me@example.com) the mail would incorrectly be verified against the block list using the comment instead of @evilcorp.com. This is a regression introduced in Forgejo v12.
  • PR (backported): fix: validate CSRF on non-safe methods All PUT/DELETE routes in the web UI are validated to prevent a cross site request forgery. Although all POST routes are validated with a CSRF token, some of the PUT/DELETE routes were missing this validation.
  • PR (backported): fix: use credential helpers for git clones When performing a git clone that requires credentials, they are temporarily stored in files and used with Git credential. They were previously included in the URL that were readable by a user with shell access to the host running the Forgejo instance when, for instance, they ask for the list of process (ps).
  • PR (backported): fix: consistently enforce 2FA on OpenID 2.0
  • PR (backported): fix: delete old auth token upon replacing primary email When the primary email is changed before it is validated, the URL sent for validation purposes must be invalidated. It was previously possible use to delay use of the URL to validate the primary email and modify the primary email in the meantime. It allowed to validate the newer primary email using the older primary email, effectively bypassing validation.
  • PR (backported): fix: require password login for creation of new token Obtaining a personal access token via the API is no longer possible if the password used for basic authentication is an API token or an OAuth2 token: it has to be the user password. Such privilege escalation was only possible for tokens with write permissions to the user. This requirement is already enforced when API calls are made with an authorization header as described in the documentation, but it was not enforced with basic authentication. As a consequence it was possible for an API token with write:user permissions or an OAuth2 token to obtain a new token with a wider or identical scope.
  • PR (backported): fix: ensure GetUserByEmail only considers validated emails Only validated emails can be used to:
  • assert if a signature can be trusted or,
  • to assign comments, issues to an existing user during a migration

The emails that were not yet validated could previously used as if they were validated, incorrectly showing commits as trusted or assigning comments, issues to the user associated with this email during migrations.

Existing migrations are not modified when they were incorrectly assigned to an email that is not validated. The trust status of all commit signatures will now show differently depending on the validation status of an email.

  • PR (backported): fix: don't allow credentials in migrate/push mirror URL It is no longer possible to specify the user and password when providing a URL for migrating a repository, the fields dedicated to that purpose on the form must be used instead. This is to prevent that those credentials are displayed in the repository settings that are visible by the repository admins, in the case where the migration is a mirror.
  • PR (backported): fix: only redirect to a new owner (organization or user) if the user has permissions to view the new owner

Full release notes for 12.0.2

12.0.3 – 12.0.4: no action items (2 versions)

13.0.0 2025-10-16

Note

A companion blog post provides additional context on this major release.

This release contains a regression when RENDER_CONTENT_MODE = iframe is set in app.ini that sometime forces the height to be 300px. It will be fixed in Forgejo v13.0.1.

Breaking

  • Breaking features
  • PR: bump the minimum required Git version from 2.0.0 to 2.34.1
  • PR: Forgejo Actions workflows are verified with a YAML schema and common errors such as using an incorrect context (e.g. ${{ badcontext.FORGEJO_REPOSITORY }}) or a typo in a required keyword (e.g. ruins-on: instead of runs-on:) will be reported in the action page and the web page that displays the file in the repository. It is recommended to verify existing workflows are successfully verified prior to upgrading, as explained in the Forgejo runner release notes.

Breaking

  • Breaking bug fixes
  • PR: The artifact-url ouput returned by the upload-artifact@v4 action can be used to download the artifact. It was previously 404. To implement this compatibility fix, the web UI URL to download artifacts (i.e. /{owner}/{repo}/actions/runs/{run_id}/artifacts/{artifact_name}) now relies on an identifier that is unique accross the instance. URLs to download artifacts that were bookmarked or copied prior to this change use an id relative to the repository and will no longer work. It previously was /{owner}/{repo}/actions/runs/{run_index}/artifacts/{artifact_name}, note the difference between {run_id} and {run_index}. The new URL can be obtained again by visiting the parent page, which still uses the relative id (/{owner}/{repo}/actions/runs/{run_index}).

Full release notes for 13.0.0

13.0.1 2025-10-17

Note

Warning if your instance was already migrated to Forgejo v13.0.0 and is using a PostgreSQL database, make sure you read the releases notes to verify Forgejo Actions secrets are sound.

Full release notes for 13.0.1

13.0.2 2025-10-26

Note

Forgejo v13.0.2 contains critical security fixes. Originally scheduled for 7 November, the release date of these patches was advanced because a vulnerability had been leaked publicly.

Vulnerability (Critical): prevent writing to out-of-repo symlink destinations while evaluating template repos

When creating a repository based upon a template repository, Forgejo reads the contents of the template repository files, expands variables within the file content, and writes a new file for use in the newly created repository. In the event that the template repository file was a symlink to a file outside of the repository, Forgejo would follow this symlink to read, expand content, and write to the target of the symlink.

This can be exploited to cause corruption to files on the Forgejo server or container that the server process has write access to.

In specific configurations, it is possible to exploit this vulnerability to gain remote shell access to a Forgejo server. Specifically, remote shell access can be achieved if:

  • The paths of sensitive files are known or guessable to an attacker,
  • Git access is available through ssh,
  • Forgejo provides ssh access through an authorized_keys file, which means:
  • The internal ssh server is not used; [server].START_SSH_SERVER=false, which is a default.
  • Forgejo manages an authorized_keys file; [server].SSH_CREATE_AUTHORIZED_KEYS_FILE=true, which is a default.
  • And, an attacker can craft the necessary repositories.

The creation of repositories based upon template repositories is being fixed by sandboxing the file access to within the newly created repository, preventing any known symlink or path traversal attack.

Vulnerability (Medium): prevent .forgejo/template from being out-of-repo content

When creating a repository based upon a template repository, Forgejo reads the contents of the .forgejo/template (or .gitea/template) file in the repository in order to identify which files are to be templated content. In the event that the .forgejo/template file was a symlink to a file outside of the repository, Forgejo would follow this symlink to read this file. This can be exploited to cause resource exhaustion in the Forgejo server, affecting service availability.

This issue is fixed by sandboxing the file access to within the newly created repository, preventing any known symlink or path traversal attack.

Vulnerability (Medium): return on error if an LFS token cannot be parsed

If LFS is enabled on a Forgejo instance with [server].LFS_START_SERVER = true (this is not the default), it was possible for a user to download LFS files for which the OID is known in advance from a private repository to which they did not have read access. This is fixed by returning on error in case the LFS token is invalid instead of returning an inconsistent state.

Vulnerability (Low): prevent commit API from leaking user's hidden email address on valid GPG signed commits

When a signed GPG commit is accessed through the /repos/{owner}/{repo}/git/commits/{sha} API, the verified commit's author's primary email address is exposed in the commit.verification.signer.email field in violation of the author's desire to keep their email address private.

This has been fixed by returning the signature’s identity, rather than the account's private email address, which is consistent with what is stored in the Git repo and returned by git log.

Go 1.25 Upgrade

To provide both the highest confidence in the security of these fixes, as well as to maintain full backwards compatibility with the current Forgejo behaviour, an upgrade to go 1.25 was required in order to use their path-traversal resistant os.Root APIs which had new APIs added in go 1.25.

We recognize that this is an unfortunate change to make in security patches for major versions, and could be difficult for Forgejo packagers to adapt to.

If necessary, a go 1.24 implementation of these security fixes is also included in this release, and go.mod can be patched to use go 1.24. The go 1.24 implementation carries the same security guarantees, but introduces two known behaviour changes. These are edge cases in repository template expansion which are unlikely to affect end-users, but unfortunately could not be addressed safely in go 1.24:

  • In the event that a template repo has a file path with a substitution in it, and the file mode is executable, the new file in the target repo will not be executable (and the executable file gets removed).
  • In the event that a template repo has a file path with a substitution in it, and the file is a symlink to another in-repo file, the old behaviour would have been to write through the symlink to the file and then rename the symlink; the new behaviour is to write a regular file in-place of the symlink and delete the symlink.

Full release notes for 13.0.2

13.0.3 – 13.0.4: no action items (2 versions)

13.0.5: released after 14.0.0; not on this route

14.0.0 2026-01-15

Breaking

  • Breaking security features
  • PR: If SSH is enabled and an authorized_keys file is managed by Forgejo, when Forgejo starts up it will read the SSH authorized_keys file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a security risk is present that must be addressed. The server administrator can address this problem either by deleting the authorized_keys file, which Forgejo will regenerate with valid keys; or by disabling the new check by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true in their app.ini file.

Breaking

  • Breaking bug fixes
  • PR: fix!: paginate GET /api/v1/admin/hooks response
  • PR: fix!: Prevent forked .profile repositories from displaying profile content. When a user forked a repository named .profile without having created their own .profile repository, the content from the forked repository was unexpectedly displayed on their public profile page. This could lead to users' profiles displaying content they did not intentionally create for that purpose. Forked .profile repositories are now treated as standard repositories and do not populate the user's public profile page. Users who wish to use the content from a forked .profile repository can convert the fork to a regular repository in the "Danger Zone" section of Repository settings. This issue was particularly problematic on instances where users had repository creation limits (-1) and would inappropriately use forked .profile repositories to obtain profile customization.
  • PR: Forgejo subcommands which only accept flag options would previously ignore any command-line arguments that were not flags and silently proceed to execute the command. This could lead to unexpected effects; for example, --must-change-password false is actually parsed as two arguments, --must-change-password, and false, where the false argument was ignored. In order to prevent misunderstandings where the user may have intended a supported argument format (--must-change-password=false), the presence of extra arguments that are not flags will now result in an error. Users of the Forgejo CLI who are relying on the previous behavior will find their commands are now resulting in errors.

Full release notes for 14.0.0 · companion blog post

14.0.1 2026-01-17

Note

This release includes an upgrade of Go version with security fixes. The issues addressed by this update do not pose any risk to the system or data security of Forgejo deployments, only potential for denial of service attacks.

Full release notes for 14.0.1

14.0.2 – 14.0.4: no action items (3 versions)

14.0.5: released after 15.0.0; not on this route

15.0.0 2026-04-16

Breaking

  • Breaking features
  • PR: remove admin-level permissions from repo-specific & public-only access tokens
  • PR: The template generation (POST /repos/{template_owner}/{template_repo}/generate) and repository deletion (DELETE /repos/{username}/{reponame}) APIs have been updated to require the same permission scope as creating a new repository. Either write:user or write:organization is required, depending on the owner of the repository being created or deleted.
  • PR: Accessing the /repositories/{id} API with a public-only access token did not restrict read access to only public repositories, which is now prevented.
  • PR: Accessing the /repos/{owner}/{repo}/issues/{index}/dependencies and /repos/{owner}/{repo}/issues/{index}/blocks APIs with a public-only access token had access to modification operations against private repositories in the form component of the API (not the URL component), which is now prevented.
  • PR: Accessing the /repos/{owner}/{repo}/issues/{index}/dependencies and /repos/{owner}/{repo}/issues/{index}/blocks APIs with a public-only access token could view dependencies or blocking issues from private repositories, which is now prevented.
  • PR: Accessing the /repos/{owner}/{repo}/issues/{index}/timeline API with a public-only access token could view comment cross-references from private repositories, which is now prevented.
  • PR: Accessing the /teams/{id}/repos/{org}/{repo} API with a public-only access token could view private repositories assigned to a team, which is now prevented.
  • PR: Access the watched repos and starred repos of a your own user through /user/subscriptions and /user/starred APIs with a public-only access token could view private repositories, which is now prevented.
  • PR: implement repo-specific access tokens in relevant search & list APIs. Breaking: the following APIs could previously return private repositories when using a public-only access token, but can no longer do so: /user/repos, /users/{username}/repos, /orgs/{org}/repos, and /teams/{id}/repos.
  • PR: implement repo-specific access tokens broadly for universal API permission checks. Breaking: API access with a public-only access token would previously return a 403 Forbidden error when attempting to access a private repository where the repository is on the API path. As part of incorporating the public-only logic into the centralized permission check, these APIs will now return 404 Not Found instead, consistent with how most permission checks are implemented in order to reduce the risk of data probing through error messages.

Breaking

  • Breaking bug fixes
  • PR: fix(ui)!: Remove the instance configuration option repository.pull-request.ADD_CO_COMMITTER_TRAILERS (was enabled by default). It was responsible for addition of unexpected trailers to commit messages in squash merges. These trailers were Co-authored-by: and Co-committed-by:. Both used the pull request author as value, who is also assigned as the author of the squash merge commit, which they were just repeating. Furthermore, Co-committed-by: is an uncommon commit trailer, and there is only one committer for a commit. The trailers were being added by Forgejo while performing the merge, bypassing user input in the UI and weren't shown in it. See further description and more examples in #11097.

Breaking

  • Breaking changes without a feature or bug label
  • PR: In Forgejo v8.0.0, the default location for the config file was changed from /etc/gitea/app.ini to /var/lib/gitea/custom/conf/app.ini. Backward compatibility logic and startup warnings were added to container setup and entrypoint scripts. Now they are removed. This change only affects those using container deployments with rootless images. If you have the config file stored in a volume bound to container's /etc/gitea, move it to the new location or override the environment variable GITEA_APP_INI. An unused volume /etc/gitea can be safely removed from the container after moving the config or if the deployment never used versions prior to v8.0.0.
  • PR (backported): chore(Dockerfile.rootless): update shadowed env variables
  • PR: Make cookie names brand independent. Attention: All users need to re-login, if you haven't manually set a cookie name in the settings. This can be prevented by changing the remember me cookie back to gitea_incredible

Full release notes for 15.0.0 · companion blog post

15.0.1 – 15.0.4: no action items (4 versions)

15.0.5 2026-07-15

Note

Also see a security announcement. Manual action is needed for some v15 deployments, as well as for upgrade to v16.0.0.

Full release notes for 15.0.5

15.0.6 – 15.0.9: released after 16.0.0; not on this route

16.0.0 2026-07-16

Note

Learn more about most notable changes and addressing the breaking changes in our news post: Forgejo v16.0 is available.

Git hooks are now stored in a centralized location instead of being duplicated in every repository, and Git hook example files are no longer generated for new repositories. While a backwards-compatible change, your instance can benefit from following an upgrade guide to clean up these files for the existing repositories. As always, make sure you to have a usable backup before upgrading!

Breaking

  • Breaking security bug fixes
  • PR: remove default 'REVERSE_PROXY_TRUSTED_PROXIES = *' from docker config
  • PR: Improved compliance with the config settings [migrations].ALLOWED_DOMAINS, [migrations].BLOCKED_DOMAINS, and [migrations].ALLOW_LOCALNETWORKS, which control the remotes that Forgejo can access for git & LFS migration and mirroring operations, fixing time-of-check vs. time-of-use issue and missing checks in LFS. git mirror HTTP operations have been adjusted to never follow HTTP redirects in order to ensure that these settings are followed, which will break HTTP mirroring if a redirect is served by the git HTTP remote.

Breaking

  • Breaking bug fixes
  • PR: use proper ${{ forgejo.ref }} in scheduled workflows
  • PR: return API URL in the url field for pull requests using the API

Full release notes for 16.0.0

16.0.1 – 16.0.5: no action items (5 versions)

Release notes from codeberg.org/forgejo/forgejo/src/branch/forgejo/release-notes-published, checked 17 hours ago. Only text the vendor marks as breaking, or puts in a warning/caution/important note, is shown; read the full notes for anything else. Forgejo's release notes list breaking changes under “Breaking …” bullets; those are quoted as “Breaking”. Text the maintainers write above the generated list, and the 7.0.0 “Migration warning” and “Regressions and workarounds” lists, and the hand-written 7.0.3, 7.0.5 and 7.0.6 items (container image, regreSSHion, removed features), and the 10.0.2 “Bug fixes” item on removed TOTP secrets, are quoted as “Note”. Covered from 7.0.0; the 1.18–1.21 releases (tags like v1.21.11-1) are not. The companion blog posts on forgejo.org are not quoted; the full release notes link to them.