(release-3008.1)=
# Salt 3008.1 release notes

<!---
Do not edit this file. This is auto generated.
Edit the templates in doc/topics/releases/templates/
for a given release.
-->


<!--
Add release specific details below
-->

<!--
Do not edit the changelog below.
This is auto generated.
-->
## Changelog

### Changed

- Changed `salt.returners.redis_return` to enumerate the Redis keyspace [#69037](https://github.com/saltstack/salt/issues/69037)
- with `SCAN` instead of the blocking `KEYS pattern` command in both [#69037](https://github.com/saltstack/salt/issues/69037)
- `get_jids` and `clean_old_jobs`. `KEYS` walks the entire keyspace [#69037](https://github.com/saltstack/salt/issues/69037)
- synchronously and stalls the Redis server for the duration; on a [#69037](https://github.com/saltstack/salt/issues/69037)
- master with hundreds of thousands of jobs this can block all clients [#69037](https://github.com/saltstack/salt/issues/69037)
- of that Redis instance for seconds. `SCAN` is incremental and [#69037](https://github.com/saltstack/salt/issues/69037)
- non-blocking. Order of returned keys is no longer guaranteed (the [#69037](https://github.com/saltstack/salt/issues/69037)
- returner does not rely on order); operators with custom scripts that [#69037](https://github.com/saltstack/salt/issues/69037)
- read `ret:*` or `load:*` directly may see them in a different order. [#69037](https://github.com/saltstack/salt/issues/69037)


### Fixed

- Fixed ``win_pkg`` functions ignoring the ``saltenv`` setting in minion configuration. All public functions (``refresh_db``, ``genrepo``, ``install``, ``remove``, ``list_pkgs``, ``latest_version``, ``upgrade_available``, ``list_upgrades``, ``list_available``, ``version``, ``get_repo_data``, ``get_package_info``) now fall back to ``__opts__["saltenv"]`` when ``saltenv`` is not passed explicitly, instead of always defaulting to ``base``. [#38551](https://github.com/saltstack/salt/issues/38551)
- Added ``encoding`` parameter to ``file.replace`` execution module and state to support UTF-16, UTF-32, and other multi-byte encoded files that would otherwise be incorrectly treated as binary. [#52793](https://github.com/saltstack/salt/issues/52793)
- Improved documentation for the `runas` and `password` parameters in `cmd.run`, `cmd.script`, and all `salt.modules.cmdmod` execution functions on Windows. The docs now accurately describe when a password is required: only when the salt-minion is **not** running as SYSTEM or as an elevated Administrator. Removed the inaccurate claim that the target user account must be in the Administrators group. Also changed `cmd.script` to log a warning instead of hard-failing when `runas` is used without a password on Windows, since a password is not always required. [#57951](https://github.com/saltstack/salt/issues/57951)
- Fixed `SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC` errors in the VMware cloud driver by reconnecting when a cached vCenter service instance is found to be stale or corrupted (for example when inherited across a fork by salt-cloud's parallel provider queries). [#61983](https://github.com/saltstack/salt/issues/61983)
- Fixed event signature verification failing under ``minion_sign_messages``. The minion was signing the return load before ``salt.channel.client.AsyncReqChannel._package_load`` attached transport metadata (``nonce``, ``ts``, ``tok``, ``id``), so the bytes the master re-serialized to verify did not match what was signed and every signed return was dropped. Signing is now performed inside ``_package_load`` after the metadata is attached, against the same bytes the master verifies. [#68181](https://github.com/saltstack/salt/issues/68181)
- Fixed two distinct bugs in the `salt.engines.redis_sentinel` engine that [#69031](https://github.com/saltstack/salt/issues/69031)
- together prevented it from being usable. `start()` no longer raises [#69031](https://github.com/saltstack/salt/issues/69031)
- `AttributeError: 'dict_values' object has no attribute 'pop'` on Python 3 [#69031](https://github.com/saltstack/salt/issues/69031)
- (the dict.values() result is now wrapped in `list(...)`). `Listener` and [#69031](https://github.com/saltstack/salt/issues/69031)
- `start()` now accept an optional `password` argument and forward it to [#69031](https://github.com/saltstack/salt/issues/69031)
- the redis client, allowing the engine to authenticate against a Sentinel [#69031](https://github.com/saltstack/salt/issues/69031)
- that requires AUTH; the default of `None` keeps existing configurations [#69031](https://github.com/saltstack/salt/issues/69031)
- working unchanged. [#69031](https://github.com/saltstack/salt/issues/69031)
- Fixed `salt.returners.redis_return` silently ignoring the documented [#69032](https://github.com/saltstack/salt/issues/69032)
- `redis.password` configuration option. The returner now reads [#69032](https://github.com/saltstack/salt/issues/69032)
- `redis.password` from config (in both regular and proxy modes) and [#69032](https://github.com/saltstack/salt/issues/69032)
- forwards it to both the single-server `redis.StrictRedis` and the [#69032](https://github.com/saltstack/salt/issues/69032)
- `StrictRedisCluster` constructors. Operators with auth-protected Redis [#69032](https://github.com/saltstack/salt/issues/69032)
- no longer lose every job return to a hidden `NOAUTH Authentication [#69032](https://github.com/saltstack/salt/issues/69032)
- required` failure; deployments without a password are unaffected. [#69032](https://github.com/saltstack/salt/issues/69032)
- Fixed three closely-related bugs in `salt.cache.redis_cache` that [#69033](https://github.com/saltstack/salt/issues/69033)
- together broke hierarchical-bank semantics: [#69033](https://github.com/saltstack/salt/issues/69033)
- `_build_bank_hier` now registers each child bank name in both the [#69033](https://github.com/saltstack/salt/issues/69033)
- parent's `$BANK_` set (consumed by `flush()` tree traversal) and the [#69033](https://github.com/saltstack/salt/issues/69033)
- parent's `$BANKEYS_` set (consumed by `list_()`); `_get_banks_to_remove` [#69033](https://github.com/saltstack/salt/issues/69033)
- now decodes the bytes returned by `smembers` and skips the `"."` [#69033](https://github.com/saltstack/salt/issues/69033)
- placeholder, so recursive `flush()` of a parent bank actually descends [#69033](https://github.com/saltstack/salt/issues/69033)
- into sub-banks instead of corrupting the path; and `flush(bank)` of a [#69033](https://github.com/saltstack/salt/issues/69033)
- sub-bank now removes the flushed bank's own reference from its [#69033](https://github.com/saltstack/salt/issues/69033)
- parent's index sets so `list_(parent)` no longer reports it as [#69033](https://github.com/saltstack/salt/issues/69033)
- present. Together these fixes restore `cache.list("minions")`, [#69033](https://github.com/saltstack/salt/issues/69033)
- `salt-run manage.present` and `salt-run manage.up` for masters [#69033](https://github.com/saltstack/salt/issues/69033)
- configured with `cache: redis`. [#69033](https://github.com/saltstack/salt/issues/69033)
- Fixed `salt.tokens.rediscluster` being unable to retrieve any eauth [#69035](https://github.com/saltstack/salt/issues/69035)
- token. The cluster client was created with `decode_responses=True`, [#69035](https://github.com/saltstack/salt/issues/69035)
- which caused `redis_client.get()` to return `str` and broke [#69035](https://github.com/saltstack/salt/issues/69035)
- `salt.payload.loads` (msgpack rejects `str`); it also caused [#69035](https://github.com/saltstack/salt/issues/69035)
- `redis_client.keys()` to return `str` and broke [#69035](https://github.com/saltstack/salt/issues/69035)
- `[k.decode("utf8") for k in ...]` (`str` has no `.decode`). Both [#69035](https://github.com/saltstack/salt/issues/69035)
- errors were swallowed by broad `except Exception` handlers, so eauth [#69035](https://github.com/saltstack/salt/issues/69035)
- appeared to silently reject every token. `decode_responses=True` is [#69035](https://github.com/saltstack/salt/issues/69035)
- removed; values now round-trip as bytes through msgpack as the rest [#69035](https://github.com/saltstack/salt/issues/69035)
- of the module already expected. [#69035](https://github.com/saltstack/salt/issues/69035)
- Fixed `salt.returners.redis_return` leaking `<minion>:<fun>` last-jid [#69038](https://github.com/saltstack/salt/issues/69038)
- pointer keys indefinitely. The pointer was written with `pipeline.set` [#69038](https://github.com/saltstack/salt/issues/69038)
- and no `ex=` TTL, so any (minion, fun) pair that stopped running stuck [#69038](https://github.com/saltstack/salt/issues/69038)
- in Redis forever -- O(minions × distinct funcs) keys accumulating over [#69038](https://github.com/saltstack/salt/issues/69038)
- the lifetime of the master. The pointer now expires on the same TTL [#69038](https://github.com/saltstack/salt/issues/69038)
- as the rest of the returner data (`keep_jobs_seconds`). Operators with [#69038](https://github.com/saltstack/salt/issues/69038)
- external scripts reading these keys directly may observe them [#69038](https://github.com/saltstack/salt/issues/69038)
- expiring; the documentation never promised they would not. [#69038](https://github.com/saltstack/salt/issues/69038)
- Fixed `salt.returners.redis_return.get_fun` always returning an [#69039](https://github.com/saltstack/salt/issues/69039)
- empty dict. The function read return data from a `<minion>:<jid>` [#69039](https://github.com/saltstack/salt/issues/69039)
- key that no other code in the module ever wrote -- a leftover from [#69039](https://github.com/saltstack/salt/issues/69039)
- an older storage schema. It now reads from the canonical [#69039](https://github.com/saltstack/salt/issues/69039)
- `ret:<jid>` hash via `HGET ret:<jid> <minion>`, matching the [#69039](https://github.com/saltstack/salt/issues/69039)
- storage layout that `returner` actually produces and the read [#69039](https://github.com/saltstack/salt/issues/69039)
- pattern that `get_jid` already uses. [#69039](https://github.com/saltstack/salt/issues/69039)
- ``cmd.run`` and friends no longer include the ``env`` and ``stdin`` arguments in the ``CommandExecutionError`` raised when the underlying subprocess fails to start (typically ``ENOENT`` / binary not found). Both fields routinely carry credentials passed in by the caller (``env={"DB_PASSWORD": "..."}``, password piped via ``stdin``), and the error message ends up in master/minion logs and in event-bus return data visible to the API caller. [#69075](https://github.com/saltstack/salt/issues/69075)
- * Relenv 0.22.14 [#69129](https://github.com/saltstack/salt/issues/69129)
- - Update python 3.14 to 3.14.6 [#69129](https://github.com/saltstack/salt/issues/69129)
- - Update sqlite to 3.53.2.0 [#69129](https://github.com/saltstack/salt/issues/69129)
- - Update openssl to 3.5.7 [#69129](https://github.com/saltstack/salt/issues/69129)
- Fix pillar masking leaking ``**********`` into rendered pillar and state values. ``MaskedDict`` / ``MaskedList`` ``__repr__`` / ``__str__`` now consult the ``salt.utils.secret.mask_pillar`` ContextVar, so ``{{ pillar['list_or_dict_value'] }}`` interpolations on the minion return plain values inside a render bracket. Hoist the ``mask_pillar=False`` bracket from ``render_pillar`` to ``compile_pillar`` so ``ext_pillar`` handlers and the rest of the master-side pillar build also run unmasked. [#69160](https://github.com/saltstack/salt/issues/69160)
- Fixed Windows MSI self-upgrade via ``pkg.install`` failing with error 1603. The old product's ``DeleteConfig_DECAC`` custom action was unconditionally deleting ``ROOTDIR\var`` during ``RemoveExistingProducts``, destroying the MSI that ``pkg.install`` had cached to ``ROOTDIR\var\cache`` before launching the upgrade. Users who had ``REMOVE_CONFIG=1`` persisted in the registry (from checking "On uninstall" at install time) hit a worse variant where the entire ``ROOTDIR`` was deleted. The fix checks ``UPGRADINGPRODUCTCODE`` — set by Windows Installer whenever an uninstall is triggered by a major upgrade — and skips all ``ROOTDIR`` deletion during upgrades, matching the behaviour of the NSIS installer which has always preserved ``ROOTDIR`` during upgrades. [#69219](https://github.com/saltstack/salt/issues/69219)
- Fixed `TypeError: string indices must be integers` in the minion when the master returns a bare string error response (e.g. `"bad load"`, `"Some exception handling minion payload"`) for a pillar request. The minion now raises a clean `AuthenticationError` instead of crashing, allowing the caller to retry or fail gracefully. [#69228](https://github.com/saltstack/salt/issues/69228)
- pkg.list_patches in yumpkg.py parses tdnf output on Photon OS [#69229](https://github.com/saltstack/salt/issues/69229)
- Restore Python dependencies in the PyPI sdist by including ``requirements/*.in`` and ``requirements/**/*.lock`` in ``MANIFEST.in``. After the requirements ``.txt`` → ``.in`` rename, the sdist no longer shipped the files that ``setup.py`` reads to populate ``install_requires``, so ``pip install salt`` produced an installation with no dependencies. [#69244](https://github.com/saltstack/salt/issues/69244)
- Fix `salt-cloud` failing to start with `AttributeError: module 'salt' has no attribute 'minion'` by importing `salt.minion` in `salt.cloud`. [#69281](https://github.com/saltstack/salt/issues/69281)
- Ensure multiple masters have their own job/state queues [#69308](https://github.com/saltstack/salt/issues/69308)
- Fixed minion state queue replacing the master-assigned JID on queued state runs, so returns now come back tagged with the JID the master actually published. [#69386](https://github.com/saltstack/salt/issues/69386)
- Made the salt user's home directory and the relenv ``extras-<py-ver>`` directory configurable in the Linux packaging. The DEB preinst scripts now source ``/etc/default/salt-setup`` (and ``/etc/sysconfig/salt-minion-setup`` for cross-distro parity with RPM) before applying the ``SALT_HOME``/``SALT_USER``/``SALT_GROUP``/``SALT_NAME`` defaults, mirroring the long-standing RPM behavior. A new ``SALT_EXTRAS_DIR`` override is honored by both stacks so the extras tree can be relocated outside ``/opt/saltstack/salt`` and its ownership is correctly restored on upgrade. [#69402](https://github.com/saltstack/salt/issues/69402)


### Added

- Added ``dsc_resource`` execution module and state module for invoking individual [#43718](https://github.com/saltstack/salt/issues/43718)
- PowerShell DSC resources directly via ``Invoke-DscResource``, without compiling [#43718](https://github.com/saltstack/salt/issues/43718)
- a MOF file or involving the Local Configuration Manager. The [#43718](https://github.com/saltstack/salt/issues/43718)
- ``dsc_resource.managed`` state provides idiomatic Salt state management for any [#43718](https://github.com/saltstack/salt/issues/43718)
- installed DSC resource module. [#43718](https://github.com/saltstack/salt/issues/43718)
- fix etcdv3 module authentification when using etcd3-py lib [#69202](https://github.com/saltstack/salt/issues/69202)
