Juju 4.0.15ยถ
๐๏ธ 23 Sep 2026
This is a bug fix release for Juju 4.0, covering changes from 4.0.14 to
4.0.15. It also adds Kubernetes service-link configuration and Google Cloud
storage and image-selection options.
๐ฏ Highlightsยถ
Storage and removal workflows are more predictable: Kubernetes filesystem import is restored, model destruction handles detached storage, and removal commands correctly report which storage will be detached or destroyed.
Controller availability and diagnostics improve: lease expiry continues after an HA controller is removed, introspection no longer waits indefinitely for a Dqlite leader, and status reporting is more consistent.
Secrets and access checks are tighter: fixes cover secret-backend draining, suspended cross-model relations, relation-status authorization, SSH key validation, file-storage paths, and certificate verification.
Bootstrap, provisioning, and migration are more reliable: fixes cover proxies, controller address selection, model defaults, Kubernetes migration metadata, and Azure resource cleanup. Google Cloud gains opt-in Hyperdisk support and the
image-idconstraint.
Full list of changes: https://github.com/juju/juju/compare/v4.0.14โฆv4.0.15
๐ ๏ธ Fixesยถ
๐ Security, access, and dependency maintenanceยถ
Relation-status updates now validate the authenticated unit and its applicationโs participation in the relation. SSH key parsing rejects input containing multiple keys, and file-storage operations reject paths that escape the storage directory. Certificate verification includes intermediate certificates, avoiding incorrect trust prompts and connection failures for valid certificate chains.
The release also updates Go to 1.26.6 and refreshes dependencies, including
golang.org/x/crypto to v0.57.0 and golang.org/x/net to v0.59.0.
fix(ssh): reject public key data describing more than one key
fix: check if application is controller โ also includes the final dependency updates.
๐ Secrets and cross-model accessยถ
Secret draining now grants access to secrets that have not yet reached the destination backend. Vault drain tokens can create secrets as well as update existing ones. Cross-model secret access is denied as soon as a relation is marked suspended, rather than waiting for the relation hooks to complete. Remote secret retrieval also avoids an unnecessary retry delay when macaroon authentication needs renewal.
๐๏ธ Storage import, status, and removalยถ
Kubernetes juju import-filesystem can import PersistentVolumes again, including
forced import of Juju-managed claims with ownership checks and protection against
concurrent claim changes and duplicate imports.
Model destruction now accounts for detached storage and respects the
--destroy-storage and --release-storage choices. Without an explicit choice,
persistent storage is checked before changing the modelโs lifecycle state.
Controller destruction waits for hosted models to be removed before tearing down
the controller, preventing orphaned Kubernetes model namespaces.
Removal commands and their dry runs again report which attached storage will be
detached or destroyed. Classification uses ownership scope, including volume-less
filesystems and unprovisioned volumes; --destroy-storage overrides detachment.
Storage status correctly reports volume persistence, and add-storage preserves
the configured size when no size override is supplied.
fix(removal): make destroy-model handle detached storage JUJU-10264
fix(cli): wait for hosted models to be removed before destroying the controller
feat(application): restore storage removal classification on destroy
fix(storage): classify removal by ownership scope rather than persistence
fix(storage): thread persistent flag through storage instance status chain
fix(application): fix test-charm-storage-aws for juju 4.0 โ also fixes the zero-size
add-storageregression.
๐งฑ Controller availability, status, and diagnosticsยถ
The lease-expiry worker now runs on every controller node. Removing the node running singular workers therefore no longer stops lease expiry and prevents another node from taking over those workers.
Introspection uses bounded contexts when gathering dependency-engine and Dqlite leader information, reporting a leader lookup error rather than hanging indefinitely. This improves diagnostics; it does not introduce a new HA health monitoring or automatic recovery system.
Application status messages are deterministic when units share the highest severity: the leader is preferred when it has that severity, otherwise the lowest-numbered matching unit is selected. Machine agent versions are restored to full status output, provider instance status is recorded before network updates, and controller-originated connections no longer interfere with model machine-presence tracking.
fix(tests): wait for voter quorum and correct HA teardown wait โ includes the runtime introspection fixes.
fix(domain/status): make derived application status deterministic
fix: machine agent version in full status and simplestream upgrade tests
fix: wait for configchange.socket before deployer starts on every machine
fix(controlsocket): use fresh password for GetUserByAuth on UserAlreadyExists
๐ Migration and API connection lifecycleยถ
Migration fixes exclude synthetic CMR relations from inappropriate local-unit
validation, preserve SQL null values in model exports, and tolerate differences
in controller-local Kubernetes rbac-id metadata while keeping authentication
attribute comparisons strict. Credential mismatch errors no longer include
credential values.
Kubernetes migration metadata no longer requires agent binaries in the object store, since those agents are distributed in OCI images, and expected migration participants are derived from unit agents rather than removed per-application operators. Model removal closes associated API connections without the startup race that could crash the controller.
These changes harden specific migration phases and data handling. Migration
from a 4.0 controller to another 4.0 controller remains unsupported; the
changes do not establish support for that path.
๐งญ Deployment, refresh, relations, and model configurationยถ
Refreshing machine charms removes empty directories left behind by the previous revision, avoiding stale Python package metadata that can break hooks. Subordinate relations no longer create units recursively, and deleted relations cannot remain in, or be restored to, committed unit relation state.
Model creation honors agent-stream defaults without leaking agent metadata into
model configuration or skipping default storage-pool and provider-resource
creation. Legacy authorized-keys model configuration sent by 3.x clients is
ignored rather than rejected; SSH keys remain separately managed in Juju 4.
CLI errors are clearer for duplicate integrations, endpoint limits, and local
files inaccessible to the confined snap. Ordinary applications named
controller can be unexposed; the actual controller application remains protected.
fix(uniter): remove empty directories left behind by charm upgrades
fix(model): consolidate CreateModel variants to fix missing storage pool seeding
fix(relation): map endpoint quota and relation-exists errors to wire codes
feat(cli): provide a clearer error message when deploying or using resources outside of confinement
โ๏ธ Providers, networking, and Kubernetes configurationยถ
Google Cloud supports additional disk types, including opt-in Hyperdisk, and the
image-id constraint with image compatibility checks. Hyperdisk availability
still depends on the selected machine family. Azure image lookup recognizes
Ubuntu 26.04 as an LTS, and controller destruction cleans up Juju-owned
resources in customer-provided resource groups without deleting the group itself.
Kubernetes bootstrap supplies proxy environment variables before downloading the controller charm. OpenStack upgrade prechecks retain proxy transport settings, and machine provisioning receives the configured OS update and upgrade settings.
Controller API address selection honors juju-mgmt-space, including VETH
addresses. Without a configured management space, non-VETH addresses are
preferred, with VETH addresses retained when they are the only candidates.
Kubernetes models gain enable-service-links, defaulting to true. Setting
juju model-config enable-service-links=false disables application service-link
environment-variable injection in generated workload pod specifications. This
retains the existing behavior by default; it does not provide network isolation
or remove the mandatory Kubernetes API service variables.
๐ Documentationยถ
Documentation adds the minimum vSphere privileges needed to operate Juju and
explains the orientation of application data in show-unit output during
upgrades. Cloud references also document the new Google Cloud options and
Kubernetes service-link setting described above.
๐ Summaryยถ
4.0.15 strengthens storage lifecycle handling, controller failover and
diagnostics, secret access, and deployment maintenance. It also improves
migration data handling, model configuration, proxy support, and cloud-provider
behavior since 4.0.14, while adding targeted Google Cloud and Kubernetes
configuration options.