⚠️ This issue respects the following points: ⚠️
Bug description
After upgrading to Nextcloud 33 (tested on 33.0.2, PHP 8.4), LDAP users get an Internal Server Error on every authenticated request. The desktop sync client cannot connect and prompts for re-login.
The root cause is UserConfig::getValueBool() passing a non-string value to strtolower(), which is a fatal TypeError in PHP 8.4.
This is distinct from #58421, which was closed by PR #59415 (fixing a lastLogin wrong appid/configkey in user_ldap). The strtolower TypeError at UserConfig.php:688 is not fixed in any released NC 33 version, and the (string) cast is not in master as of this writing.
Steps to reproduce
- Run Nextcloud 33.x on PHP 8.4
- Configure LDAP authentication (
user_ldap app)
- Attempt to log in or make any authenticated request as an LDAP user
Expected behavior
LDAP users authenticate successfully.
Actual behavior
Every authenticated request throws:
TypeError: strtolower(): Argument #1 ($string) must be of type string, string given
at /var/www/html/lib/private/Config/UserConfig.php:688
Full stack trace:
UserConfig->getValueBool($uid, 'user_ldap', 'isDeleted')
OCA\User_LDAP\User\DeletedUsersIndex->isUserMarked($uid)
OCA\User_LDAP\User_LDAP->isUserEnabled($uid)
OC\User\User->isEnabled()
OC\Authentication\Token\TokenProvider / Session->isLoggedIn()
Root cause
UserConfig::getValueBool() at line 688:
$b = strtolower($this->getTypedValue($userId, $app, $key, $default ? 'true' : 'false', $lazy, ValueType::BOOL));
getTypedValue() can return a non-string (e.g. boolean false) when the stored value type metadata doesn't align with ValueType::BOOL. PHP 8.4 made passing non-strings to strtolower() a fatal TypeError (previously a deprecation).
Fix
Add a (string) cast:
$b = strtolower((string)$this->getTypedValue($userId, $app, $key, $default ? 'true' : 'false', $lazy, ValueType::BOOL));
Temporary workaround
Docker / bare-metal:
docker exec -u www-data <container> sed -i \
's/strtolower(\$this->getTypedValue/strtolower((string)\$this->getTypedValue/' \
/var/www/html/lib/private/Config/UserConfig.php
No restart needed.
Kubernetes (Helm): see #58421 (comment) for a before-starting hook approach.
Server configuration
|
Value |
| Nextcloud version |
33.0.2 |
| PHP version |
8.4 |
| user_ldap version |
1.24.0 |
| Database |
PostgreSQL |
Logs
{
"level": 3,
"app": "PHP",
"message": "TypeError: strtolower(): Argument #1 ($string) must be of type string, string given at /var/www/html/lib/private/Config/UserConfig.php#688",
"exception": {
"Exception": "TypeError",
"Trace": [
{"file": "lib/private/Config/UserConfig.php", "line": 688, "function": "strtolower", "args": ["false"]},
{"file": "apps/user_ldap/lib/User/DeletedUsersIndex.php", "line": 88, "function": "getValueBool", "args": ["<uid>", "user_ldap", "isDeleted"]},
{"file": "apps/user_ldap/lib/User_LDAP.php", "line": 651, "function": "isUserMarked"}
]
}
}
Bug description
After upgrading to Nextcloud 33 (tested on 33.0.2, PHP 8.4), LDAP users get an Internal Server Error on every authenticated request. The desktop sync client cannot connect and prompts for re-login.
The root cause is
UserConfig::getValueBool()passing a non-string value tostrtolower(), which is a fatalTypeErrorin PHP 8.4.This is distinct from #58421, which was closed by PR #59415 (fixing a
lastLoginwrong appid/configkey inuser_ldap). ThestrtolowerTypeError atUserConfig.php:688is not fixed in any released NC 33 version, and the(string)cast is not in master as of this writing.Steps to reproduce
user_ldapapp)Expected behavior
LDAP users authenticate successfully.
Actual behavior
Every authenticated request throws:
Full stack trace:
Root cause
UserConfig::getValueBool()at line 688:getTypedValue()can return a non-string (e.g. booleanfalse) when the stored value type metadata doesn't align withValueType::BOOL. PHP 8.4 made passing non-strings tostrtolower()a fatalTypeError(previously a deprecation).Fix
Add a
(string)cast:Temporary workaround
Docker / bare-metal:
No restart needed.
Kubernetes (Helm): see #58421 (comment) for a
before-startinghook approach.Server configuration
Logs
{ "level": 3, "app": "PHP", "message": "TypeError: strtolower(): Argument #1 ($string) must be of type string, string given at /var/www/html/lib/private/Config/UserConfig.php#688", "exception": { "Exception": "TypeError", "Trace": [ {"file": "lib/private/Config/UserConfig.php", "line": 688, "function": "strtolower", "args": ["false"]}, {"file": "apps/user_ldap/lib/User/DeletedUsersIndex.php", "line": 88, "function": "getValueBool", "args": ["<uid>", "user_ldap", "isDeleted"]}, {"file": "apps/user_ldap/lib/User_LDAP.php", "line": 651, "function": "isUserMarked"} ] } }