Juju 4.0.0¶
🗓️ 14 Nov 2025
Juju 4.0.0 introduces a major architectural step toward a relational, Dqlite controller datastore and a simplified
domain model. It removes long-deprecated surfaces (e.g., series, podspec charms) and tightens CLI behavior around
bases and deployment safety. Several legacy APIs and workflows are intentionally deferred to the 4.0.x / 4.x cycle.
🎯 Highlights:¶
New controller database architecture (Dqlite-first): A relational model backed by Dqlite (high-availability SQLite via Raft).
API and watcher model refactors: The
AllWatcheris removed from4.0.Series fully retired in favor of bases: 4.0 removes the concept of distribution “series”; bases are the only way to specify OS/runtime (the 3.6 docs already steer operations toward bases).
Provider rename: The “Manual” provider type is renamed to “Unmanaged” across the codebase. Update any scripts/CI currently using ‘manual’.
🔄 Lifecycle upgrade/migrate path clarified¶
As in 3.6, upgrade-controller does not allow jumping major/minor; 4.0 upgrades are expected via model migration to a
4.0 controller.
Note
Model migration will appear in next patch versions.
⚠️ Breaking changes¶
Controller HA enablement: Use controller scaling with
juju add-unitin the controller model instead ofenable-ha. Thejuju-ha-spacecontroller config item is removed in favour of binding the controller applicationdbclusterendpoint.Default
alphaspace assumption on MAAS: There is no MAASalphaspace by default; set the default space using thedefault-space=<space>model config or bind endpoints explicitly before deploy.LXD profiles for Kubernetes workloads: LXD profiles are removed from
4.0.Base/series commands (
juju set-application-base, juju upgrade-machine / machine-upgrade): In-place base or series switching via these commands is removed; use charm-defined upgrade flows.SSH Key Management: Your SSH keys are no longer automatically added to newly created models. After creating a new model, you must manually add your SSH keys using the
juju add-ssh-keycommand if you want to usejuju sshto access machines in that model.Kubernetes podspec charms (and
k8s-set / k8s-gethook commands): Podspec charms no longer run; move to modern sidecar charms.Filesystem import: Importing filesystems is not implemented at GA. Deferred to 4.0.x.
Leader settings (
leader-get, leader-set): Leader settings and the associated hook commands are removed.AllWatcher: Legacy watchers are removed; a lighter event API will replace them.
Series → Bases (
deploy/add-machinescenarios): Series were deprecated in3.xand are removed in4.0; bases are required.Export bundle (
juju export-bundle): Command removed.KVM provider: KVM support is removed; use LXD with
virtual-machineconstraint.Ubuntu fan networking: Fan networking is removed; migrate to alternative networking.
Deploy from directory (
juju deploy <local-dir>): Juju no longer packages directories for deploy; use Charmcraft to build them, then juju deploy the built artifact.Environment variable:
JUJU_TARGET_SERIESis removed from context; useJUJU_TARGET_BASE.Safer deploy/refresh switches around bases
juju deploy --forceno longer allows deploying to a base not declared by the charm.juju refresh --force-seriesremoved; use--force-base.
Status API filtering: Server-side
StatusArgs.Patterns[]filtering is removed (migrate to client-side filtering until a replacement arrives).Offers update (
juju offer): Updating an existing offer is removed; use create/remove flows.Provider type rename (
manual→unmanaged): Update all relevant cloud commands, bootstrap scripts, CI, and docs.Wait-for:
juju wait-for(and subcommandswait-for model|application|machine|unit) — removed. In3.6this family streamed deltas and let you express goal states via a small DSL; it’s no longer available in4.0. Workarounds: polljuju status --format=json(optionally with--watch <interval>) and evaluate readiness client-side.private-addressremoved: it is no longer automatically maintained in relation data. It was a copy ofingres-address, which is the only value that should be used now.
🐛 Known issues / deferred items¶
Model migrations (
≤3.x→4.0): not available at GA; planned for4.0.xLXD profiles for Kubernetes workloads: planned for
4.xWatcher API replacement: new, lighter event API to land during
4.xServer-side status filtering replacement: client-side filtering only for now; a new server-side mechanism is planned for 4.x
SSH keys are no longer automatically added to newly created models.
📘 Summary¶
Juju 4.0.0 represents a significant architectural milestone, delivering a scalable controller foundation built
on Dqlite while streamlining the operational model through the removal of legacy features. While this major version
introduces breaking changes that require migration planning, it sets the stage for a more maintainable and performant
Juju experience. Charm authors and operators should review the breaking changes and migration guidance above to ensure
a smooth transition to 4.0.0.