Skip to content

wekan

v9.99 Feature

This release adds 2 notable features for engineering teams evaluating rollout.

Published 9d Productivity & Wikis
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

docker javascript kanban meteor real-time sandstorm
+2 more
snapcraft wekan

Affected surfaces

auth breaking_upgrade

Summary

AI summary

Updates https://github.com/wekan/wekan/issues/6469, https://github.com/wekan/wekan/issues/6467, and fix across a mixed release.

Changes in this release

Performance Medium

Removes FerretDB SQLite connection pool limit of 16, improving cursor‑heavy load performance.

Removes FerretDB SQLite connection pool limit of 16, improving cursor‑heavy load performance.

Source: llm_adapter@2026-07-17

Confidence: high

Bugfix High

Fixes LDAP connection leak that exhausted directory server with too many open connections.

Fixes LDAP connection leak that exhausted directory server with too many open connections.

Source: llm_adapter@2026-07-17

Confidence: high

Bugfix Medium

Adds timeout and diagnostics to FerretDB startup wait, preventing WeKan from hanging indefinitely.

Adds timeout and diagnostics to FerretDB startup wait, preventing WeKan from hanging indefinitely.

Source: llm_adapter@2026-07-17

Confidence: high

Full changelog

v9.99 2026-07-17 WeKan ® release

This release fixes the following BUG:

  • LDAP connection leak: WeKan exhausted the directory server with "too many open connections"
    (#6467, #6469).
    Operators reported that after an update WeKan "dies really quickly", that restarting the server did not
    help, and that it "kills our openldap server with too many open connections"; others saw logins hang for
    minutes and then fail with "Must be logged in". Root cause: every LDAP login attempt
    (packages/wekan-ldap/server/loginHandler.js) and every background sync run
    (packages/wekan-ldap/server/sync.js) created a fresh new LDAP() and called connect(), but the code
    never called disconnect() on any path — success, failure, or fallback. Each login attempt (including
    every failed one) and each background-sync tick (every minute by default) therefore leaked one socket to
    the LDAP/AD server. Over time this grew without bound until the directory server hit its per-client
    connection limit and started refusing connections, which took it — and, with it, every WeKan login — down.
    • Fixed by guaranteeing the connection is always released:
      • A small shared helper packages/wekan-ldap/server/connectionGuard.js (runWithLdapDisconnect(ldap, fn))
        runs the work and disconnect()s in a finally, on every exit path. The disconnect is best-effort and
        never masks the original result or error.
      • The LDAP login handler now runs its whole flow through runWithLdapDisconnect, so connect() is always
        paired with a disconnect() — on a successful login, a thrown Meteor.Error, or a fallback to the
        default account system.
      • The background sync() releases its connection in a finally, and importNewUsers() disconnects only
        the connection it opened itself (never a connection borrowed from sync()).
      • The admin ldap_test_connection method (packages/wekan-ldap/server/testConnection.js), which had the
        same leak, now disconnects on both the success and failure paths, so repeated "Test Connection" clicks
        no longer leak either.
      • LDAP.disconnect() is now a safe no-op when connect() was never reached, so cleanup can never throw.
    • Tests (tests/ldapConnectionRelease.test.cjs, added to test:unit:node): behavioural coverage of the
      guard (disconnects after success and returns the result; disconnects exactly once; disconnects and
      re-throws when the work throws — the failed-login path that exhausted OpenLDAP), negative cases (a failing
      disconnect never turns a success into a failure nor hides the real error; a missing/null ldap is
      tolerated), plus source-level guards that the leak-prone call sites actually route through the guard and
      that connect() lives inside the guarded region.
    • Thanks to the reporting operators and xet7 (fix).

This release also updates the bundled FerretDB (see the fork's own CHANGELOG Upcoming): the SQLite backend
connection pool no longer caps MaxOpenConns at 16, which had starved WeKan's cursor-heavy load and made
boards take minutes to load and logins fail with "Must be logged in" (#6467,
#6469).

  • Snap: FerretDB never becoming ready made WeKan hang with no web port and no explanation
    (#6476). With database=ferretdb, snap-src/bin/wekan-control
    waits for FerretDB to accept connections before starting WeKan — WeKan does not open its HTTP port until
    the database answers. That wait loop had no timeout and no diagnostics: if FerretDB never started
    listening (a crashed or CPU/architecture-incompatible per-arch binary, a locked or corrupt SQLite database,
    or the FerretDB service left disabled by a failed migration hand-off), WeKan blocked there forever. The
    service showed as active, but the port never opened and the only symptom was a silent
    FerretDB not ready yet, retrying in 5 seconds repeating — exactly what #6476 reported (Apache proxy could
    not connect to port 3333). The reporter's wekan.log stopped right after the startup env dump, confirming
    control never reached node main.js.
    • Fixed by mirroring the MongoDB branch: after WEKAN_DB_WAIT_TIMEOUT seconds (default 120,
      overridable) the FerretDB wait loop now prints an actionable hint once and keeps retrying — pointing to
      snap logs <snap>.ferretdb for the real error, naming the SQLite directory to check for locks/corruption,
      the arch-mismatch (exec format error) case, the snap start --enable <snap>.ferretdb recovery, and the
      snap set <snap> database=mongodb fallback to keep working meanwhile. This turns "port never opens, no
      clue why" into a clear message. Regression test: tests/ferretdbWaitTimeout.test.cjs, including a negative
      guard that the FerretDB wait is not a silent unbounded loop again.
    • This is a robustness/diagnostics fix; the underlying reason FerretDB was not accepting connections is
      environment-specific and lives in the FerretDB service log.
    • Thanks to uusijani (report) and xet7 (fix).

Thanks to above for their contributions.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track wekan

Get notified when new releases ship.

Sign up free

About wekan

The Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . New English strings for new features at imports/i18n/data/en.i18n.json . Non-English translations at https://app.transifex.com/wekan/wekan only.

All releases →

Related context

Beta — feedback welcome: [email protected]