Forgejo v14.0 is available

Forgejo v14.0, the lightweight, community-developed, self-hosted platform for code collaboration, was released on 15 January 2026. You will find a short selection of the changes it introduces below and a complete list in the release notes.

A dedicated test instance is available to try it out. Before upgrading it is strongly recommended to make a full backup as explained in the upgrade guide and carefully read all breaking changes from the release notes. If in doubt, do not hesitate to ask for help in the chat room.

Summary

Forgejo v14.0 improves everyday usability while strengthening reliability and safety.

Issue and pull request search gains simple inline filters, the web editor switches to a lighter experience, and more parts of the interface work smoothly without JavaScript. In addition, a new stateless CSRF protection allows keeping tabs open for a long time and to resume work without interruptions.

Forgejo Actions adds finer-grained trust controls, better visibility for queued jobs and advanced concurrency and dynamic matrix support. Forgejo’s operational reliability has also been enhanced with database deadlock fixes and foreign‑key improvements.

Administrators are recommended to review Commit Status Cleanup for information about an optional post-upgrade data cleanup procedure.

UI features

Search syntax support for Issues and PRs

Several simple search filters are now available in Issue/PR search. Information about usage of these filters is accessible through in-app documentation (click the question mark located adjacent to the search bar) and via the dedicated documentation page. Dropdown filters are compatible with the new simple search filters. [PR]

Demonstration of filtering and sorting list of issues with query is:open author:administrator sort:comments:asc

New file editor

The previous web file editor, Monaco by Microsoft, was overly complex for single-file edits and had issues with performance, loading times, accessibility and mobile usability. It has been replaced with a lighter-weight editor CodeMirror, which is better suited to this use case and resolves the previously mentioned issues.

The new code editor with a new html file open

Switch between formats when previewing CITATION.{cff,bib} files

When previewing a CITATION file (CFF or BIB), a switch allows for switching between formats (other formats could be added, though some libraries have incompatible licenses). The “Cite repository” menu item now links directly to this preview page instead of opening a popup. [PR]

View of the BibTex version of a CFF (Citation File Format), with the format switcher visible in the top-left

Interact with UI without JavaScript

Work has progressed on making the Forgejo web UI functional without JS. A bug has been fixed, making it possible to post comments without JS enabled. Several ellipsis menus have been made accessible, including the user menu in the navbar. There are now more expandable elements that work without JS.

Improvements to Forgejo actions

Pull Request Trust Management

Forgejo’s ability to “Approve” actions execution from a pull request has been enhanced with new options to approve once, always, and deny execution. Once a user is approved for execution, abuse can also be managed by revoking access for execution. [PR]

Trust management area. The new UI section says: Some workflows are waiting to be reviewed. Available buttons: Deny, Approve once, Approve always

Commit Status Cleanup

During the Forgejo 14 development cycle, a bug was discovered in Actions that caused many redundant records to be added to the commit_status table while an action was running. In most cases, these records have accumulated since Actions was first developed, affecting all users. A fix for that defect has been introduced in Forgejo 14.

The Forgejo CLI has been augmented with a doctor cleanup-commit-status command which can be used to cleanup redundant records. When the Forgejo Devops team executed this tool on the code.forgejo.org instance, 14.9 million out of 15.2 million records (97%) were identified as redundant records caused by this bug.

$ forgejo doctor cleanup-commit-status --dry-run
2026/01/13 10:43:29 ...git/commit_status.go:527:CleanupCommitStatus() [I] Reviewed 15297011 records in commit_status, and would delete 14916470
2026/01/13 10:43:29 ...git/commit_status.go:531:CleanupCommitStatus() [I] Cleanup commit status took 488488 milliseconds

Two options for the tool allow the administrator to control the memory usage as records are inspected (--buffer-size 100000) and the number of records deleted in each DELETE query (--delete-chunk-size 1000).

Forgejo instances running on SQLite may experiencing locking errors while the cleanup-commit-status command is running due to two processes accessing the same SQLite database files. For a typical SQLite-based instance with few users and light load, this is likely to be short-lived. For a larger SQLite-based instance, it is recommended to run with a smaller delete chunk size, or to run the command while Forgejo is offline.

”Waiting” status Display

Actions that are waiting for a runner with a specific configuration will display this information in the UI, enabling users to easily diagnose why jobs may not be running as expected. [PR]

Actions job with description: Waiting for a runner with the following labels: ...

Concurrency Groups

Forgejo Actions now supports the concurrency block in order to either permit or restrict concurrent execution of a Forgejo Actions workflow. [PR]

jobs:
  rust-checks:
    runs-on: debian-latest
    steps:
      - run: sleep 300

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

Dynamic Matrices & Runs-On

Forgejo Actions now supports matrix jobs and runs-on fields that are defined by earlier jobs in the workflow, allowing a workflow to apply custom logic to determine how and where its jobs will run. In this example, the define-matrix job would be a placeholder for custom logic, such as inspecting the changes in a pull request, to determine which jobs to spawn in the runs-on-dynamic-matrix job:

jobs:
  define-matrix:
    runs-on: docker
    steps:
      - id: define
        run: |
          echo 'array=["debian-bookworm", "debian-trixie"]' >> "$FORGEJO_OUTPUT"
    outputs:
      array-value: ${{ steps.define.outputs.array }}

  runs-on-dynamic-matrix:
    needs: define-matrix
    strategy:
      matrix:
        my-runners: ${{ fromJSON(needs.define-matrix.outputs.array-value) }}
    runs-on: ${{ matrix.my-runners }}
    steps:
      - run: uname -a

[PR 1], [PR 2]

Security features

Validation of the authorized_keys file

When Forgejo is configured to use the authorized_keys file for SSH, upon startup this file will be read and its contents will be validated. If any unexpected keys are found in the file, Forgejo will terminate its startup in order to signal to the server administrator that a security risk is present that must be addressed. [PR]

2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either:
Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys.
Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file.
        Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys

Stateless CSRF protection

CSRF attacks are now prevented via a stateless method that uses browser fetch metadata request headers. Because it is stateless, you can now submit work on tabs that have been open for more than 24 hours. Forgejo instances that are hosted on a subpath are no longer protected against CSRF attacks from services that are hosted on the same origin (same scheme, host/domain and port). Anti-CSRF tokens are therefore no longer used and the CSRF_COOKIE_HTTP_ONLY option was removed. [PR]

Database improvements

Goodbye “Pull requests -1” caused by DB Deadlocks

Forgejo maintains statistics on repos, labels, and milestones which have been subject to internal deadlocks when being updated, often surfacing to the user as an indicator that they have “-1” pull requests on a repository. Following scalability work on these calculations, the number of database deadlocks resulting in incorrect statistics or even interrupting merge operations has been effectively reduced to zero. [6 related PRs]

Database foreign keys

Forgejo now implements a limited number of foreign keys in the database. About 5% of the cross-table references that Forgejo uses are protected from data inconsistencies by database foreign keys, which will be created automatically while upgrading to Forgejo 14. [6 related PRs]

Records that previously should have been deleted due to removal of their relationship are considered to be data inconsistencies, and may prevent the creation of a foreign key. For example, if an access token exists in the access table which references a user who was previously deleted, this record should have been removed when the user was deleted but this was never guaranteed by the database due to the lack of foreign keys.

Forgejo will automatically identify these data inconsistencies and correct them to create the necessary foreign keys, deleting the inconsistent records. This will not have any functional impact to your Forgejo instance.

The affected tables and the number of records are reported in the logs during the database migration if any are found.

Distributed database queries

In Forgejo v12 a new feature was introduced to distribute read queries over multiple databases. During testing conducted by Codeberg it was found that this behavior was almost never used. This has been fixed in this release and distributing read queries over multiple databases is now effective. We should note that this is not a high availability feature, there’s no mechanism to stop sending queries to a database that is offline. [PR]

Release schedule and Long Term Support

Based on the release schedule, major releases are published every three months. Patch releases are published more frequently, depending on the severity of the bug or security fixes they contain. Forgejo v14.0 is a non-LTS release that replaces the previous non-LTS release, Forgejo v13.0. It will be supported until 16 April 2026.

VersionRelease dateEnd Of Life
11.0 (LTS)16 April 202516 July 2026
13.016 October 202515 January 2026
14.015 January 202616 April 2026
15.0 (LTS)16 April 202615 July 2027

14.0-test daily releases

Releases are built daily from the latest changes found in the v14.0/forgejo development branch. They are deployed to the https://v14.next.forgejo.org instance for manual verification in case a bug fix is of particular interest ahead of the next patch release. It can also be installed locally with:

Their names are staying the same but they are replaced by new builds every day.

Get Forgejo v14.0

See the download page for instructions on how to install Forgejo, and read the release notes for more information.

Upgrading

Carefully read the breaking bug fixes section of the release notes.

The actual upgrade process is as simple as replacing the binary or container image with the corresponding Forgejo binary or container image. If you’re using the container images, you can use the 14.0 tag to stay up to date with the latest 14.0.Y patch release automatically.

Make sure to check the Forgejo upgrade documentation for recommendations on how to properly backup your instance before the upgrade.

Contribute to Forgejo

If you have any feedback or suggestions for Forgejo do not hold back, it is also your project. Open an issue in the issue tracker for feature requests or bug reports, reach out on the Fediverse, or drop into the Matrix space (main chat room) and say hi!

Forgejo is proud to be funded transparently. Additionally, it accept donations through Liberapay. It is also possible to donate to Codeberg e.V. in case the Liberapay option does not work out for you, and part of the funding is used to compensate for work on Forgejo.

However, the Liberapay team allows for money to go directly to developers without a round-trip to Codeberg. Additionally, Liberapay allows for a steady and reliable funding stream next to other options, a crucial aspect for the project. The distribution of funds through Liberapay is transparently controlled using the decision-making process, and Forgejo contributors are encouraged to consider applying to benefit from this funding opportunity.

Thank you for using Forgejo and considering a donation, in case your financial situation allows you to.