🐡 Updating OpenBSD

Four commands for four kinds of update: patches for the running release, packages, firmware and the next release, with the output of a real OpenBSD 8.0 machine.

Video: Updating OpenBSD (OpenBSD video)
Prefer to watch? This short video runs this page's main commands on a real OpenBSD 8.0 machine, with on-screen captions and a synthetic voiceover (an AI voice trained on the author's own recording). Click to play, or watch it on YouTube.
doas syspatch                  # security and reliability patches
doas pkg_add -u                # update all packages
doas sysupgrade -n             # fetch the next release, do not reboot

OpenBSD splits updating in four: syspatch for fixes to the release you run, pkg_add -u for packages, fw_update for firmware and sysupgrade for the next release. This page runs each one, including how to undo a patch.

Every example ran for real on OpenBSD 8.0 (amd64) in a virtual machine, as an ordinary user with doas. The output you see is the output the machine gave.

Four kinds of update, four commands

On Linux one command, apt or dnf, updates everything. OpenBSD splits the job in four, and each part has its own tool:

 - syspatch installs binary security and reliability fixes for the release you are running.
 - sysupgrade moves the whole system to the next release.
 - pkg_add -u updates the packages you installed.
 - fw_update fetches firmware for hardware that needs it.

Every example below ran for real on OpenBSD 8.0 in a virtual machine, as an ordinary user with doas. First, where the updates come from and what you are running:

$ uname -sr
OpenBSD 8.0
$ cat /etc/installurl
https://cdn.openbsd.org/pub/OpenBSD
$ syspatch -l; echo "installed patches: exit $?"
installed patches: exit 0

/etc/installurl is one line: the mirror that every one of these tools downloads from, and the installer wrote it for you. syspatch -l lists the patches already applied, and on a fresh install there are none.

syspatch: fixes for the running release

OpenBSD does not ship a new version of a program to fix a bug in it. It publishes a patch against the release you have, and syspatch applies it. First ask what is available. This is the command to put in cron, because it only lists and changes nothing:

$ doas syspatch -c
001_ppp
002_nsd
003_aesgmac
004_video
005_dbupdate
006_isakmpd
008_pffq
009_unveil

Each name is one errata entry. Patches are cumulative, so you cannot pick a subset. Apply them all:

$ doas syspatch
Get/Verify syspatch80-001_ppp.tgz
Installing patch 001_ppp
Get/Verify syspatch80-002_nsd.tgz
Installing patch 002_nsd
Get/Verify syspatch80-003_aesgmac.tgz
Installing patch 003_aesgmac
Get/Verify syspatch80-004_video.tgz
Installing patch 004_video
Get/Verify syspatch80-005_dbupdate.tgz
Installing patch 005_dbupdate
Get/Verify syspatch80-006_isakmpd.tgz
Installing patch 006_isakmpd
Get/Verify syspatch80-008_pffq.tgz
Installing patch 008_pffq
Get/Verify syspatch80-009_unveil.tgz
Installing patch 009_unveil
Relinking to create unique kernel... done; reboot to load the new kernel
Errata can be reviewed under /var/syspatch
$ syspatch -l
001_ppp
002_nsd
003_aesgmac
004_video
005_dbupdate
006_isakmpd
008_pffq
009_unveil

syspatch downloads each patch, verifies its signature, saves the files it is about to replace, then installs it. The last two lines matter: a patch touched the kernel, so syspatch relinked it and wants a reboot. The patch descriptions stay on the machine:

$ ls /var/syspatch | head -3
80-001_ppp
80-002_nsd
80-003_aesgmac

If you run syspatch on a machine that has just been installed, it can answer "cannot apply patches while reorder_kernel is running". OpenBSD relinks its kernel in a random order on the first boot, which takes a few minutes. Wait, then run it again.

Undoing a patch

Every patch saves what it replaced, so a patch can be reverted. -r reverts the most recent one:

$ doas syspatch -r
Reverting patch 009_unveil
Relinking to create unique kernel... done; reboot to load the new kernel
$ syspatch -l | tail -2
006_isakmpd
008_pffq
$ doas syspatch -c
009_unveil

The patch is back in the available list, and syspatch with no options installs it again:

$ doas syspatch
Get/Verify syspatch80-009_unveil.tgz
Installing patch 009_unveil
Relinking to create unique kernel... done; reboot to load the new kernel
Errata can be reviewed under /var/syspatch
$ doas syspatch -c; echo "available patches left: exit $?"
available patches left: exit 0

Nothing is left to apply. syspatch -R would revert all of them, which is rarely what you want.

Packages: pkg_add -u

Packages have their own tool and are updated on their own schedule. Install one and look at what is installed:

$ doas pkg_add tree
quirks-7.227 signed on 2026-11-04T22:14:26Z
$ pkg_info
quirks-7.227        exceptions to pkg_add rules
tree-0.62           print ascii formatted tree of a directory structure
updatedb-0p0        pkg_add speed up cache
vmm-firmware-1.16.3p12 SeaBIOS and EDK II binary images for vmd(8)

pkg_add says nothing when it succeeds, which is the Unix way and takes some getting used to. The first thing pkg_add prints is the line about quirks: the package system refreshing its own list of known problems. Now update. -n is a dry run that shows what would change and changes nothing:

$ doas pkg_add -un
quirks-7.227 signed on 2026-11-04T22:14:26Z
$ doas pkg_add -u; echo "exit $?"
quirks-7.227 signed on 2026-11-04T22:14:26Z
exit 0

pkg_add -u with no names updates every installed package, and when everything is current it prints nothing more. Each package is built for the OpenBSD release you run, so an update stays inside that release. To update one package, give its name:

$ doas pkg_add -u tree; echo "exit $?"
quirks-7.227 signed on 2026-11-04T22:14:26Z
exit 0

Packages are not patched by syspatch, and syspatch does not touch packages. Run both.

Firmware: fw_update

Wi-Fi cards, some network cards and graphics chips need firmware blobs that the base system does not ship. fw_update looks at the hardware, downloads what is missing and keeps it current. Dry run first:

$ doas fw_update -n
fw_update: add none; update none; keep vmm

On this virtual machine the answer is: nothing to add, nothing to update. On a laptop it usually finds something. The installer and syspatch both call fw_update for you, so most of the time you never run it by hand.

sysupgrade: the next release

A release upgrade is one command. sysupgrade downloads the next release's files, checks their signatures, stores a new installer kernel as /bsd.upgrade and reboots into it. The options that matter:

$ man sysupgrade | col -b | sed -n 14,34p
     them with signify(1), and copies bsd.rd to /bsd.upgrade.

     sysupgrade by default then reboots the system.  The bootloader will
     automatically choose /bsd.upgrade, triggering a one-shot upgrade using
     the files in /home/_sysupgrade.

     The options are as follows:

     -b base-directory
	     Download files to base-directory/_sysupgrade instead of
	     /home/_sysupgrade.

     -f	     For snapshots, force an already applied upgrade.  This option has
	     no effect on releases.

     -k	     Keep the files in /home/_sysupgrade.  By default they will be
	     deleted after the upgrade.

     -n	     Fetch and verify the files and create /bsd.upgrade but do not
	     reboot.

-n is the one to use first: it downloads and verifies everything and stops before the reboot. The time this page was tested, 8.0 was the newest release, so there was nothing to move to:

$ doas sysupgrade -n -R 8.1; echo "exit $?"
Fetching from https://cdn.openbsd.org/pub/OpenBSD/8.1/amd64/
sysupgrade: Error retrieving https://cdn.openbsd.org/pub/OpenBSD/8.1/amd64/SHA256.sig: 404 Not Found
exit 1

Asking for a version that does not exist yet is an error, not a change, and nothing was left behind:

$ ls /bsd.upgrade /home/_sysupgrade 2>&1 | head -2
ls: /bsd.upgrade: No such file or directory
/home/_sysupgrade:

When a new release does exist, read its upgrade notes at openbsd.org before you run sysupgrade. OpenBSD supports upgrading one release at a time. Take a backup of /etc first.

A routine that fits in a cron job

Put together, a patch routine is short. This is the whole thing, written to a file and run:

$ printf '%s\n' 'syspatch -c' 'pkg_add -un' 'fw_update -n' > /tmp/check.sh
$ cat /tmp/check.sh
syspatch -c
pkg_add -un
fw_update -n

Run it as root and it tells you what is waiting:

$ doas ksh /tmp/check.sh
quirks-7.227 signed on 2026-11-04T22:14:26Z
fw_update: add none; update none; keep vmm

Put the same lines in the root crontab with crontab -e and cron mails you the output every morning. Then apply by hand, in this order: syspatch, pkg_add -u, reboot if the kernel was patched. sysupgrade is a separate, planned event once or twice a year. Do the patching on a schedule and the system never falls far behind.