What happened?
On 3008, eauth tokens are deleted by the master's periodic token maintenance almost immediately after issuance, regardless of token_expire. A token works for the first request or two, then fails with Authentication error occurred. (HTTP 401 via salt-api / "Authentication denied" in pepper). Master log shows:
Token '<tok>' could not be loaded (TokenExpiredError('')); removing it from the store.
A token is effectively valid only until the next maintenance sweep (0–~60s), not for token_expire (default 12h). This breaks any operation that holds a token longer than one quick round-trip — most notably salt-api batch jobs, which gather and wait the per-chunk timeout (default 60s) before issuing saltutil.find_job, by which point the token is already gone.
Scope / affected versions: 3008.0 and 3008.1. Not present in 3006.x or 3007.x. Independent of eauth backend (pam/file/etc.) and of netapi module — it's in the master-side token cache, so plain salt-api and auth.mk_token are affected equally.
Steps to reproduce:
- On a 3008 master with token_expire set well above 60s (e.g. default), obtain a token (/login, or salt-run auth.mk_token).
- Reuse that same token after ~60s (or simply run a salt-api local_batch job).
- Observe the 401 / TokenExpiredError even though the token is far from its real expiry.
- Expected: a token remains valid until token_expire.
- Actual: the token is purged on the next maintenance sweep (within ~60s).
Root cause
Introduced in 3008.0 by 78685e5 ("Provide token storage using the salt.cache interface"), which moved token storage onto the generic salt.cache interface. Two defects in that commit: (1) the generic Cache.clean_expired() fallback compares each entry's file mtime (always in the past) against now, so it flushes every entry on every sweep; (2) LoadAuth.mk_token passes the absolute expiry timestamp to Cache.store(expires=...), which expects a duration in seconds. 3006/3007 stored tokens via the localfs token driver and never hit this path.
Type of salt install
Official deb
Major version
3007.x
What supported OS are you seeing the problem on? Can select multiple. (If bug appears on an unsupported OS, please open a GitHub Discussion instead)
ubuntu-24.04
salt --versions-report output
Salt Version:
Salt: 3008.1
Python Version:
Python: 3.14.6 (main, Jun 11 2026, 02:19:05) [GCC 11.2.0]
Dependency Versions:
cffi: 2.0.0
cherrypy: 18.10.0
cryptography: 48.0.0
dateutil: 2.9.0.post0
docker-py: Not Installed
gitdb: 4.0.12
gitpython: 3.1.50
Jinja2: 3.1.6
libgit2: Not Installed
looseversion: 1.3.0
M2Crypto: Not Installed
Mako: Not Installed
msgpack: 1.1.2
msgpack-pure: Not Installed
mysql-python: Not Installed
packaging: 24.0
pycparser: 3.00
pycrypto: Not Installed
pycryptodome: 3.23.0
pygit2: Not Installed
python-gnupg: 0.5.6
PyYAML: 6.0.3
PyZMQ: 27.1.0
relenv: 0.22.14
smmap: 5.0.2
timelib: 0.3.0
Tornado: 6.5.7
ZMQ: 4.3.5
Salt Package Information:
Package Type: onedir
System Versions:
dist: ubuntu 24.04.3 noble
locale: utf-8
machine: x86_64
release: 6.14.0-1017-gcp
system: Linux
version: Ubuntu 24.04.3 noble
What happened?
On 3008, eauth tokens are deleted by the master's periodic token maintenance almost immediately after issuance, regardless of token_expire. A token works for the first request or two, then fails with Authentication error occurred. (HTTP 401 via salt-api / "Authentication denied" in pepper). Master log shows:
A token is effectively valid only until the next maintenance sweep (0–~60s), not for token_expire (default 12h). This breaks any operation that holds a token longer than one quick round-trip — most notably salt-api batch jobs, which gather and wait the per-chunk timeout (default 60s) before issuing saltutil.find_job, by which point the token is already gone.
Scope / affected versions: 3008.0 and 3008.1. Not present in 3006.x or 3007.x. Independent of eauth backend (pam/file/etc.) and of netapi module — it's in the master-side token cache, so plain salt-api and auth.mk_token are affected equally.
Steps to reproduce:
Root cause
Introduced in 3008.0 by 78685e5 ("Provide token storage using the salt.cache interface"), which moved token storage onto the generic salt.cache interface. Two defects in that commit: (1) the generic Cache.clean_expired() fallback compares each entry's file mtime (always in the past) against now, so it flushes every entry on every sweep; (2) LoadAuth.mk_token passes the absolute expiry timestamp to Cache.store(expires=...), which expects a duration in seconds. 3006/3007 stored tokens via the localfs token driver and never hit this path.
Type of salt install
Official deb
Major version
3007.x
What supported OS are you seeing the problem on? Can select multiple. (If bug appears on an unsupported OS, please open a GitHub Discussion instead)
ubuntu-24.04
salt --versions-report output
Salt Version: Salt: 3008.1 Python Version: Python: 3.14.6 (main, Jun 11 2026, 02:19:05) [GCC 11.2.0] Dependency Versions: cffi: 2.0.0 cherrypy: 18.10.0 cryptography: 48.0.0 dateutil: 2.9.0.post0 docker-py: Not Installed gitdb: 4.0.12 gitpython: 3.1.50 Jinja2: 3.1.6 libgit2: Not Installed looseversion: 1.3.0 M2Crypto: Not Installed Mako: Not Installed msgpack: 1.1.2 msgpack-pure: Not Installed mysql-python: Not Installed packaging: 24.0 pycparser: 3.00 pycrypto: Not Installed pycryptodome: 3.23.0 pygit2: Not Installed python-gnupg: 0.5.6 PyYAML: 6.0.3 PyZMQ: 27.1.0 relenv: 0.22.14 smmap: 5.0.2 timelib: 0.3.0 Tornado: 6.5.7 ZMQ: 4.3.5 Salt Package Information: Package Type: onedir System Versions: dist: ubuntu 24.04.3 noble locale: utf-8 machine: x86_64 release: 6.14.0-1017-gcp system: Linux version: Ubuntu 24.04.3 noble