How to Safely Upgrade FreeBSD Between Major Versions
A careful, step-by-step process for upgrading a production FreeBSD system across major versions using freebsd-update, with a real rollback plan.
This walks through upgrading a FreeBSD system between major releases (for example, 13.x to 14.x) using freebsd-update, the standard binary upgrade path, with proper precautions at each step.
Step 1: back up first, genuinely
Before anything else, take a full backup — or, if the root filesystem is on ZFS, at minimum a snapshot of every dataset involved:
zfs snapshot -r zroot@pre-upgrade-14
This single step is what turns “the upgrade went badly” from a crisis into an inconvenience: zfs rollback can undo everything below if needed.
Step 2: read the release notes for the target version first
https://www.freebsd.org/releases/14.0R/relnotes/
Check specifically for any noted incompatibilities, deprecated features, or required manual steps — release notes for a major version jump often flag things freebsd-update itself won’t warn you about (deprecated rc.conf options, changed default behaviors).
Step 3: check current system state before starting
freebsd-version
uname -a
pkg check -d
Confirm the currently-installed packages are in a consistent state (per pkg check -d) before layering an OS upgrade on top of a possibly-already-broken package state.
Step 4: fetch the upgrade
freebsd-update -r 14.0-RELEASE upgrade
This compares your current installed files against both your current release and the target release, and downloads only what’s needed. It will prompt you to review and potentially merge configuration file changes — read these prompts carefully rather than blindly accepting defaults, especially for /etc/ files you’ve customized.
Step 5: install the first pass
freebsd-update install
This first install pass updates the kernel. Reboot into the new kernel before continuing — the process is explicitly staged this way so you can confirm the new kernel boots successfully before the second pass touches userland:
shutdown -r now
Step 6: complete the userland upgrade
After confirming the reboot succeeded and the system is stable on the new kernel:
freebsd-update install
This second pass updates the remaining userland binaries and libraries.
Step 7: rebuild third-party packages if needed
A major version jump can change the base system’s ABI in ways that require third-party packages to be rebuilt:
pkg-static install -f pkg
pkg upgrade
Step 8: remove old libraries only after confirming everything works
freebsd-update install
A third install invocation specifically handles removing now-obsolete shared libraries — deliberately left as a separate, final step so that if something built against an old library is still silently relying on it, you have a chance to notice and address that before those libraries disappear entirely.
Step 9: verify thoroughly before considering this done
freebsd-version -k # confirm kernel version
freebsd-version -u # confirm userland version
service -e # confirm expected services are still enabled
Test your actual critical services explicitly — a jail that should be running, a network service that should be listening — rather than just confirming version numbers match, since a clean version report doesn’t guarantee every dependent service came back up correctly.
What to do if something goes wrong
If the new kernel from step 5 doesn’t boot, select kernel.old from the loader menu to return to the previous, known-good kernel immediately. If problems surface later, after userland has also been upgraded, the ZFS snapshot from step 1 is your real safety net — zfs rollback returns the entire system to its exact pre-upgrade state, which a partial freebsd-update rollback alone cannot guarantee as cleanly.
Why the staged reboot between kernel and userland matters
Combining the kernel and userland upgrade into a single install pass with no intermediate reboot removes your ability to isolate which half of the upgrade caused a problem, if one occurs. Rebooting between the two, as outlined above, is the difference between “the new kernel didn’t boot, revert to kernel.old” being a two-minute fix, versus troubleshooting a fully-upgraded system where you can no longer tell whether the kernel or the userland change is actually responsible for whatever broke.