⚠️ This issue respects the following points: ⚠️
Bug description
I have seen this error intermittently for several users on Nextcloud 34.0.3.2. One example occurred during a background PUT /ocs/v2.php/apps/user_status/api/v1/heartbeat?format=json request. The stack goes through token-login completion and Activity's SetUserDefaults listener before failing in core UserConfig::setTypedValue():
unknown key activity configured for <redacted-user> even though insert raised a duplicate contraint
Activity is trying to save activity/configured=yes. Core handles the duplicate insert by calling loadConfigAll(), but that does not read the database again if both cache halves are already marked loaded. The newly inserted preference is still missing from valueDetails, so core throws UnknownKeyException. Activity does not catch the exception from its final configured write.
The heartbeat handler is not reached. The inspected OCS v2 error path returns HTTP 500; the supplied exception log does not itself record the HTTP response status. The exact overlapping production request has not been identified.
Steps to reproduce
This can be reproduced deterministically without timing two HTTP requests. In an isolated test fixture:
- Create two independent
OC\Config\UserConfig instances, A and B, sharing the same preferences store. Start with no preferences for a synthetic user.
- Call
B->getApps($uid) so both the fast and lazy caches are loaded while activity/configured is absent.
- Call
A->setValueMixed($uid, "activity", "configured", "yes"); the insert succeeds.
- Call the same setter on B. It encounters a uniqueness conflict and throws the exception above instead of discovering the row.
Illustrative sequence (A and B must be separate instances, not two references to the same container service):
$uid = "synthetic-user";
$b->getApps($uid);
$a->setValueMixed($uid, "activity", "configured", "yes");
$b->setValueMixed($uid, "activity", "configured", "yes"); // throws
The standalone check executed the actual installed UserConfig and Activity listener with an in-memory database double modeling unique preference keys and minimal service doubles. It also exercised the final write through SetUserDefaults::handle(new PostLoginEvent(...)).
Results:
- The exact exception escapes the Activity listener.
- Failed duplicate recovery performs zero additional database reads.
- One correct
configured=yes row remains stored.
- A fresh
UserConfig instance sees the row and Activity skips initialization.
- Control: if only the fast cache was loaded before A inserted, B performs the full reread and recovers.
The same assertions passed with the exact 34.0.4 UserConfig.php from commit 77c7284fed1f5c7b4bce1a94299e229f3281b606. This is method-level testing with a modeled database, not an end-to-end 34.0.4 installation, a real SQL concurrency test, or a claim that the production interleaving was captured.
Expected behavior
When another request has already inserted the same preference, core should reread the existing row and complete the normal update/no-op handling, preserving the stored type and flags. Saving an already-persisted activity/configured=yes marker should not abort login completion or an otherwise valid API request.
Nextcloud Server version
34
Operating system
Debian/Ubuntu
PHP engine version
PHP 8.5
Web server
Apache (supported)
Database engine version
MariaDB
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
Relevant context only; full production config:list output is omitted.
Accounts: LDAP/Active Directory.
Browser authentication: automatic Windows/Kerberos SSO through Apache.
user_saml type: environment-variable
user_saml general-uid_mapping: REMOTE_USER
The isolated reproduction does not use LDAP, Kerberos, or user_saml.
List of activated Apps
Relevant apps, not a full app:list dump:
- activity (bundled app; installed test copy reports 7.0.0)
- user_status (the affected heartbeat endpoint)
- user_ldap
- user_saml 8.3.1
The error is thrown by core UserConfig during Activity preference initialization.
Nextcloud Signing status
Nextcloud Logs
Redacted, shortened exception excerpt; unrelated fields and repetitive dispatcher frames omitted:
Nextcloud: 34.0.3.2
Time: 2026-09-09T06:26:56+00:00
Level: 3
Method: PUT
URL: /ocs/v2.php/apps/user_status/api/v1/heartbeat?format=json
User: <redacted-user>
Exception: OCP\Config\Exceptions\UnknownKeyException
Message: unknown key activity configured for <redacted-user> even though insert raised a duplicate contraint
Thrown at: lib/private/Config/UserConfig.php:1227
Call chain (request entry to failing write):
ocs/v2.php -> ocs/v1.php:72
-> OC::handleLogin()
-> OC\User\Session::tryTokenLogin()
-> loginWithToken()
-> completeLogin()
-> PostLoginEvent
-> OCA\Activity\Listener\SetUserDefaults::handle():37
-> SetUserDefaults::setDefaultsForUser():69
-> OC\AllConfig::setUserValue():226
-> OC\Config\UserConfig::setValueMixed():920
-> UserConfig::setTypedValue():1227
Additional info
Versions: production Nextcloud 34.0.3 (internal 34.0.3.2), Apache 2.4.66, PHP-FPM 8.5.4, MariaDB 11.8; affected browser reported Edge 152 on Windows. The standalone check ran on PHP 8.5.4. Exact installation/upgrade history and server-side encryption status were not collected.
Latest patch check: 34.0.4 was released on September 10. Its UserConfig.php is byte-for-byte identical to the 34.0.3 file tested, and the reproduction was repeated against that exact 34.0.4 source.
Source references:
Related changes: #62586 / #63093 added the explicit exception and diagnostic reason, but did not force a cache refresh. Activity #2791 catches exceptions around individual notification-default writes; the final configured marker remains outside that catch.
Bug description
I have seen this error intermittently for several users on Nextcloud 34.0.3.2. One example occurred during a background
PUT /ocs/v2.php/apps/user_status/api/v1/heartbeat?format=jsonrequest. The stack goes through token-login completion and Activity'sSetUserDefaultslistener before failing in coreUserConfig::setTypedValue():Activity is trying to save
activity/configured=yes. Core handles the duplicate insert by callingloadConfigAll(), but that does not read the database again if both cache halves are already marked loaded. The newly inserted preference is still missing fromvalueDetails, so core throwsUnknownKeyException. Activity does not catch the exception from its finalconfiguredwrite.The heartbeat handler is not reached. The inspected OCS v2 error path returns HTTP 500; the supplied exception log does not itself record the HTTP response status. The exact overlapping production request has not been identified.
Steps to reproduce
This can be reproduced deterministically without timing two HTTP requests. In an isolated test fixture:
OC\Config\UserConfiginstances, A and B, sharing the same preferences store. Start with no preferences for a synthetic user.B->getApps($uid)so both the fast and lazy caches are loaded whileactivity/configuredis absent.A->setValueMixed($uid, "activity", "configured", "yes"); the insert succeeds.Illustrative sequence (A and B must be separate instances, not two references to the same container service):
The standalone check executed the actual installed
UserConfigand Activity listener with an in-memory database double modeling unique preference keys and minimal service doubles. It also exercised the final write throughSetUserDefaults::handle(new PostLoginEvent(...)).Results:
configured=yesrow remains stored.UserConfiginstance sees the row and Activity skips initialization.The same assertions passed with the exact 34.0.4
UserConfig.phpfrom commit77c7284fed1f5c7b4bce1a94299e229f3281b606. This is method-level testing with a modeled database, not an end-to-end 34.0.4 installation, a real SQL concurrency test, or a claim that the production interleaving was captured.Expected behavior
When another request has already inserted the same preference, core should reread the existing row and complete the normal update/no-op handling, preserving the stored type and flags. Saving an already-persisted
activity/configured=yesmarker should not abort login completion or an otherwise valid API request.Nextcloud Server version
34
Operating system
Debian/Ubuntu
PHP engine version
PHP 8.5
Web server
Apache (supported)
Database engine version
MariaDB
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
Versions: production Nextcloud 34.0.3 (internal 34.0.3.2), Apache 2.4.66, PHP-FPM 8.5.4, MariaDB 11.8; affected browser reported Edge 152 on Windows. The standalone check ran on PHP 8.5.4. Exact installation/upgrade history and server-side encryption status were not collected.
Latest patch check: 34.0.4 was released on September 10. Its
UserConfig.phpis byte-for-byte identical to the 34.0.3 file tested, and the reproduction was repeated against that exact 34.0.4 source.Source references:
Related changes: #62586 / #63093 added the explicit exception and diagnostic reason, but did not force a cache refresh. Activity #2791 catches exceptions around individual notification-default writes; the final
configuredmarker remains outside that catch.