Skip to content
daniel@cosenza:~/blog
FreeBSDHow-To October 12, 2025 3 min read

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.