-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github OR Nextcloud Community Forum (I've searched it).
- Nextcloud Server is up to date. See Maintenance and Release Schedule for supported versions.
- I agree to follow Nextcloud's Code of Conduct.
Bug description
App-passwords (auth tokens) created through:
sudo -u www-data php occ user:auth-tokens:add <user>
are invalidated 5 minutes (with a few seconds difference every time) after creation. During the first 5 minutes they work perfectly for WebDAV and OCS API calls.
After ~300 seconds the next request fails with response status code 503 and:
Session token credentials are invalid
OC\Authentication\Exceptions\TokenPasswordExpiredException
and in the database the token’s password_invalid field flips from 0 → 1.
This happens both for normal local users and SAML users.
I have tried to disable external IdP, password-policy, and all background-jobs, but no I have had no difference.
Steps to reproduce
- Create a new permanent token using the user password when prompted for a password:
sudo -u www-data php occ user:auth-tokens:add <username> - Output: App password:
<app-password> - Test the password immediately:
curl -u <username>:<token> https://nextcloud-poc.dc.kau.se/remote.php/dav/files/<username>/ -I
→ Response status200 - Wait 5+ minutes.
- Repeat the same request.
→ Response status503 Service unavailable, and then401 Unauthorizedon the next one. - Check database:
SELECT id,name,type,last_activity,password_invalid FROM oc_authtoken ORDER BY id DESC LIMIT 3;
The token row now haspassword_invalid = 1.
Expected behavior
Permanent app tokens (type 1) should remain valid indefinitely unless explicitly revoked or the user password changes. They should not expire after 5 minutes nor set password_invalid = 1.
Actual behavior:
App tokens created via occ user:auth-tokens:add are invalidated after 5 minutes of inactivity, throwing TokenPasswordExpiredException on next use after 5 minutes.
Nextcloud Server version
31
Operating system
Debian/Ubuntu
PHP engine version
PHP 8.3
Web server
Apache (supported)
Database engine version
MariaDB
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
- Default user-backend (database)
- LDAP/ Active Directory
- SSO - SAML
- Other
Configuration report
{
"system": {
"instanceid": "***REMOVED SENSITIVE VALUE***",
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": [
"***REMOVED SENSITIVE VALUE***"
],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"dbtype": "mysql",
"version": "31.0.10.2",
"overwrite.cli.url": "http:\/\/localhost",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"mysql.utf8mb4": true,
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"maintenance": false,
"defaultapp": "",
"loglevel": "0",
"updater.secret": "***REMOVED SENSITIVE VALUE***",
"theme": "",
"memcache.local": "\\OC\\Memcache\\APCu",
"memcache.distributed": "\\OC\\Memcache\\Redis",
"redis": {
"host": "***REMOVED SENSITIVE VALUE***",
"port": 6379,
"timeout": 1.5
}
}
}List of activated Apps
Enabled:
- activity: 4.0.0
- app_api: 5.0.2
- bruteforcesettings: 4.0.0
- cloud_federation_api: 1.14.0
- dashboard: 7.11.0
- dav: 1.33.0
- federatedfilesharing: 1.21.0
- federation: 1.21.0
- files: 2.3.1
- files_downloadlimit: 4.0.0
- files_pdfviewer: 4.0.0
- files_sharing: 1.23.1
- files_trashbin: 1.21.0
- files_versions: 1.24.0
- logreader: 4.0.0
- lookup_server_connector: 1.19.0
- notifications: 4.0.0
- oauth2: 1.19.1
- profile: 1.0.0
- provisioning_api: 1.21.0
- recommendations: 4.0.0
- related_resources: 2.0.0
- serverinfo: 3.0.0
- settings: 1.14.0
- support: 3.0.0
- text: 5.0.2
- theming: 2.6.1
- twofactor_backupcodes: 1.20.0
- updatenotification: 1.21.0
- user_saml: 7.0.0
- viewer: 4.0.0
- workflowengine: 2.13.0
Disabled:
- admin_audit: 1.21.0
- circles: 31.0.0 (installed 31.0.0)
- comments: 1.21.0 (installed 1.21.0)
- contactsinteraction: 1.12.1 (installed 1.12.0)
- encryption: 2.19.0
- files_external: 1.23.0
- files_reminders: 1.4.0 (installed 1.4.0)
- firstrunwizard: 4.0.0 (installed 4.0.0)
- nextcloud_announcements: 3.0.0 (installed 3.0.0)
- password_policy: 3.0.0 (installed 3.0.0)
- photos: 4.0.0 (installed 4.0.0)
- privacy: 3.0.0 (installed 3.0.0)
- sharebymail: 1.21.0 (installed 1.21.0)
- survey_client: 3.0.0 (installed 3.0.0)
- suspicious_login: 9.0.1
- systemtags: 1.21.1 (installed 1.21.1)
- twofactor_nextcloud_notification: 5.0.0
- twofactor_totp: 13.0.0-dev.0
- user_ldap: 1.22.0 (installed 1.22.0)
- user_status: 1.11.0 (installed 1.11.0)
- weather_status: 1.11.0 (installed 1.11.0)
- webhook_listeners: 1.2.0 (installed 1.2.0)Nextcloud Signing status
No errors have been found.Nextcloud Logs
{"reqId":"sGsBzm35CWuZpynmopPD","level":2,"time":"2025-11-10T08:38:02+00:00","remoteAddr":"<ip_adress>","user":"--","app":"core","method":"GET","url":"/remote.php/dav/files/<username>/","message":"Login failed: '<username>' (Remote IP: '<ip_adress>')","userAgent":"curl/8.7.1","version":"31.0.10.2","data":{"app":"core"}}
{"reqId":"sGsBzm35CWuZpynmopPD","level":2,"time":"2025-11-10T08:38:02+00:00","remoteAddr":"<ip_adress>","user":"--","app":"core","method":"GET","url":"/remote.php/dav/files/<username>/","message":"Session token credentials are invalid","userAgent":"curl/8.7.1","version":"31.0.10.2","data":{"app":"core","user":"<username>"}}
{"reqId":"sGsBzm35CWuZpynmopPD","level":3,"time":"2025-11-10T08:38:02+00:00","remoteAddr":"<ip_adress>","user":"--","app":"no app in context","method":"GET","url":"/remote.php/dav/files/<username>/","message":"Exception thrown: OC\\Authentication\\Exceptions\\TokenPasswordExpiredException","userAgent":"curl/8.7.1","version":"31.0.10.2","exception":{"Exception":"OC\\Authentication\\Exceptions\\TokenPasswordExpiredException","Message":"","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Authentication/TokenPublicKeyTokenProvider.php","line":152,"function":"checkToken","class":"OC\\Authentication\\Token\\PublicKeyTokenProvider","type":"->"},{"file":"/var/www/html/lib/private/Authentication/Token/Manager.php","line":121,"function":"getToken","class":"OC\\Authentication\\Token\\PublicKeyTokenProvider","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/User/Session.php","line":413,"function":"getToken","class":"OC\\Authentication\\Token\\Manager","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Auth.php","line":80,"function":"logClientIn","class":"OC\\User\\Session","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php","line":103,"function":"validateUserPass","class":"OCA\\DAV\\Connector\\Sabre\\Auth","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Auth.php","line":191,"function":"check","class":"Sabre\\DAV\\Auth\\Backend\\AbstractBasic","type":"->"},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Auth.php","line":105,"function":"auth","class":"OCA\\DAV\\Connector\\Sabre\\Auth","type":"->"},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Auth/Plugin.php","line":179,"function":"check","class":"OCA\\DAV\\Connector\\Sabre\\Auth","type":"->"},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Auth/Plugin.php","line":135,"function":"check","class":"Sabre\\DAV\\Auth\\Plugin","type":"->"},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"beforeMethod","class":"Sabre\\DAV\\Auth\\Plugin","type":"->"},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":456,"function":"emit","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Server.php","line":49,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/html/apps/dav/lib/Server.php","line":403,"function":"start","class":"OCA\\DAV\\Connector\\Sabre\\Server","type":"->"},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":21,"function":"exec","class":"OCA\\DAV\\Server","type":"->"},{"file":"/var/www/html/remote.php","line":145,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Authentication/Token/PublicKeyTokenProvider.php","Line":226,"message":"","exception":{},"CustomMessage":"Exception thrown: OC\\Authentication\\Exceptions\\TokenPasswordExpiredException"}}
{"reqId":"sGsBzm35CWuZpynmopPD","level":3,"time":"2025-11-10T08:38:02+00:00","remoteAddr":"<ip_adress>","user":"--","app":"webdav","method":"GET","url":"/remote.php/dav/files/<username>/","message":"OC\\Authentication\\Exceptions\\TokenPasswordExpiredException: ","userAgent":"curl/8.7.1","version":"31.0.10.2","exception":{"Exception":"Sabre\\DAV\\Exception\\ServiceUnavailable","Message":"OC\\Authentication\\Exceptions\\TokenPasswordExpiredException: ","Code":0,"Trace":[{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Auth/Plugin.php","line":179,"function":"check","class":"OCA\\DAV\\Connector\\Sabre\\Auth","type":"->"},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Auth/Plugin.php","line":135,"function":"check","class":"Sabre\\DAV\\Auth\\Plugin","type":"->"},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"beforeMethod","class":"Sabre\\DAV\\Auth\\Plugin","type":"->"},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":456,"function":"emit","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/html/apps/dav/lib/Connector/Sabre/Server.php","line":49,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->"},{"file":"/var/www/html/apps/dav/lib/Server.php","line":403,"function":"start","class":"OCA\\DAV\\Connector\\Sabre\\Server","type":"->"},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":21,"function":"exec","class":"OCA\\DAV\\Server","type":"->"},{"file":"/var/www/html/remote.php","line":145,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/apps/dav/lib/Connector/Sabre/Auth.php","Line":112,"message":"OC\\Authentication\\Exceptions\\TokenPasswordExpiredException: ","exception":{},"CustomMessage":"OC\\Authentication\\Exceptions\\TokenPasswordExpiredException: "}}Additional info
- password_invalid is set only when a request using the token is made after 5 min, not automatically by a job. Possible that the token has a cache lifetime of 5 mins?
- Upgrading from 31.0.8 → 31.0.10 and switching background jobs to AJAX makes no difference.
- The issue reproduces on a clean install with all non-core apps disabled.
- Appears to originate in PublicKeyTokenProvider.php during checkToken() / getToken(): the provider throws TokenPasswordExpiredException when it cannot verify the password hash of the token, even for permanent app tokens created via CLI.