# What changed in pydantic-settings

> 61 changes in pydantic-settings 2 from its official release notes, upgrade guides and advisories: 11 breaking, 3 security, 9 new APIs and options. Each one cited. Sources checked 2026-10-19. HTML: https://unstale.sh/pypi/pydantic-settings/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## pydantic-settings 2

### Breaking changes

- With case_sensitive=False, only registered CLI options are lowercased; arguments after -- and CliUnknownArgs values keep their case. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Each CliUnknownArgs field now receives only leftover arguments from its own subcommand. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- An empty JSON array now parses as an empty list instead of ['']. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- JSON config files are read as UTF-8 by default instead of the locale encoding; this option still overrides it. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- With this enabled, a discriminated union default is dropped only when the incoming value selects a different union member. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Python 3.10 is no longer supported; pydantic-settings now requires Python 3.11+. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- When false, aliases are ignored in every source; environment variables, secrets, CLI flags and defaults use only field names. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Takes precedence over alias when the two differ, so JSON/YAML/TOML file and CLI values load instead of being silently ignored. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- YAML config files are read as UTF-8 by default instead of the locale encoding; this option still overrides it. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- The setting now applies to init kwargs and JSON/TOML/YAML config-file sources; because it defaults to False, matching is case-insensitive for these sources. Nested keys remain case-sensitive. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Non-JSON environment values for strict fields now raise `ValidationError` instead of a less specific error. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)

### Security

- With `case_sensitive=True`, the GCP source skips the `list_secrets` call, lowering the required IAM permissions to `roles/secretmanager.secretAccessor`. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- The source no longer follows symlinks that point outside `secrets_dir`. (2.14.2) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0), [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.14.2)
- pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_dir, enabling local file read and bypassing secrets_dir_max_size (2.14.2) — [security advisory](https://github.com/advisories/GHSA-4XGF-CPJX-PC3J)

### New APIs and options

- Adds an extra for installing the AWS Systems Manager Parameter Store source. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Adds an AWS Systems Manager Parameter Store source that recursively reads parameters under an ssm_path, mapping / onto nested models. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Adds named variadic CLI options that accept multiple values after one option as well as repeated options; required fields need at least one value. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Returns a process-local singleton per settings class; calling the class directly still builds a fresh instance. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Clears the cache used for process-local cached settings instances. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Enables environment variable names to appear in generated CLI help, making `--help` output useful as configuration documentation. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Set this environment variable to a truthy value with `DEBUG` logging enabled to inspect source contributions, value precedence, and env-file or secret-file resolution. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Lets you root settings at a nested table in any TOML file, rather than only in `pyproject.toml`. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- JSON, TOML, and YAML file sources accept `Traversable` resources, allowing packaged configuration files, including files in zip or wheel distributions, to be loaded without casting to `Path`. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)

### Behavior and default changes

- Fields with unresolved forward references now emit this warning, which tells you to call `model_rebuild()`; warning-as-error configurations may turn it into a failure. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- The GCP settings source can obtain `project_id` from an earlier settings source, rather than only from the constructor or `GOOGLE_CLOUD_PROJECT`. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)

### Fixes and other changes

- A bare single-segment AliasPath no longer tries to JSON-decode plain string values. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Resolving a named Annotated type alias no longer mutates shared FieldInfo metadata, avoiding validators running twice on subclasses or after model_rebuild(). (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Case-insensitive matching now works for nested pydantic dataclasses. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Tuples, frozenset, MutableSequence and other collection subtypes, including named collection type aliases, are treated as repeatable or variadic options. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- cli_exit_on_error=False is now honored by CliSubCommand parsers, which raise SettingsError instead of exiting. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- No longer crashes when cli_prefix is set in model_config. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialized output now round-trips through CliApp.run for enums, tuples, dates, Decimal values, explicit None, empty containers, CliVariadicArg values, and populated CliUnknownArgs fields. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialization now preserves explicit None values. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialization now preserves empty containers. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialization now handles populated CliUnknownArgs fields without raising IndexError. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialized CLI output now parses for enums, tuples, dates and Decimal values. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Serialization now preserves CliVariadicArg values. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Aliases keep their case when case_sensitive=False. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Set, MutableSet and AbstractSet fields now JSON-decode environment values. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- dash_to_underscore=True now works for nested Azure Key Vault model fields. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- DotenvFiltering is now exported from pydantic_settings.sources.types. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- A bare typing.Dict field no longer raises IndexError when env_nested_delimiter is set. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Azure Key Vault and GCP Secret Manager now honor env_parse_none_str. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- With extra='allow', a non-lowercase env_prefix is now stripped from dotenv extras. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- An empty JSON config file is treated as an empty mapping instead of crashing. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Named union type aliases now decode like inline equivalents in environment and dotenv sources, including under Optional, Annotated and custom validation aliases. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- The source now validates its specific constructor arguments. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Adds support for pydantic 2.14, including fixes for CliApp.run and validate_by_alias=False handling. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Adds support for Python 3.15. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- secrets_case_sensitive=True is now honored on Windows. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- An explicit empty tuple overrides the model config to read the TOML file root. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Home-directory paths are expanded when checking whether the TOML table-header file exists. (2.16.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.16.0)
- Environment values for nested model fields using `AliasPath` are now JSON-decoded. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Environment variables now load on Windows when `case_sensitive=True`, despite `os.environ` keys being upper-cased. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Dotenv extras are no longer wrongly claimed by a complex field that shares their name prefix. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Enum names now parse through nested annotations such as `Optional[Annotated[MyEnum, ...]]` when enum parsing is enabled. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Case-insensitive field matching now works for optional nested models. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Secret subclasses no longer crash when loaded from the environment. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- Secret files are now read as UTF-8 rather than using the platform locale encoding, avoiding corruption of non-ASCII secrets on some Windows code pages. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- This package is no longer required at runtime. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
- An empty section now falls back to defaults instead of raising an `AttributeError`. (2.15.0) — [release notes](https://github.com/pydantic/pydantic-settings/releases/tag/v2.15.0)
