The Handbook

    Theme
    • Guides
        • Check a system before installing FreeBSD
        • Orient a Linux administrator on FreeBSD
        • Supported FreeBSD releases
        • Choose a FreeBSD documentation and support channel
        • Move files safely without GNU mv -t
        • Update, upgrade, or update packages?
        • Upgrade 14.4 or 15.0 to FreeBSD 15.1
        • Choose packages, ports, or poudriere
        • Choose the quarterly or latest package branch
        • Choose a FreeBSD download or package mirror
        • Make a system setting persistent
        • Configure locale, keyboard, and time zone
        • Configure a serial console for recovery
        • Choose a custom kernel, module, or loader setting
        • Run a Linux binary with the compatibility layer
        • Check desktop and laptop hardware before installation
        • Choose and check a graphics driver
        • Choose Xorg or Wayland
        • Build a maintainable desktop baseline
        • Install and check a desktop browser
        • Check laptop Wi-Fi, power, and suspend
        • Check multimedia readiness
        • Choose and configure a printing stack
        • Run Windows applications with Wine
        • Snapshot and replicate a ZFS dataset
        • Choose a filesystem and storage layout
        • Operate ZFS without losing the recovery path
        • Restore files from a ZFS snapshot
        • Read ZFS pool health and run a scrub
        • Replace a failed device in a ZFS mirror
        • Replicate a ZFS dataset over SSH
        • Change PF safely on a remote host
        • Configure a narrow WireGuard tunnel
        • Plan a FreeBSD home server
        • Choose a mail server or an outgoing relay
        • Publish a network service safely
        • Choose a jail network model
        • Choose native jails or a jail manager
        • Choose a jail or a bhyve virtual machine
        • Establish a FreeBSD security baseline
        • Choose a MAC policy
        • Audit security-relevant activity
        • Start a DTrace performance investigation
    • Integrations
        • Create a first jail with Bastille
        • Compare jail managers and OCI tooling
        • Publish a Bastille service through PF
        • Mount a ZFS dataset in a Bastille jail
        • Update and upgrade Bastille jails
        • Back up and restore a Bastille jail
        • Prepare bhyve and vm-bhyve
        • Choose NFS or Samba for file sharing
        • Choose ZFS backup automation
        • Operate a signed poudriere repository
        • Manage FreeBSD configuration with Ansible or Salt
        • Run Motion with webcamd on FreeBSD
        • Design a reverse proxy, certificates, and monitoring
    • FAQ
      • Troubleshooting
          • Recover an interrupted freebsd-update run
          • Resolve a package repository or ABI mismatch
          • Diagnose the FreeBSD boot path
          • Recover with a ZFS boot environment
          • Diagnose DNS, routing, and firewall paths
          • Diagnose network mbuf exhaustion
          • Bind a service to a low port without running it as root
          • Diagnose audio output or input
          • Diagnose webcamd, cuse, and a webcam
          • Fix USB device permissions without opening every device
      • About this handbook
      • Synopsis
      • Define the required recovery boundary
      • Identify the electrical and device path
      • Test the controlling terminal first
      • Establish firmware and loader output
      • Verify the kernel boundary
      • Add a login only when required
      • Test recovery and rollback
      • Primary references

      Configure a serial console for recovery

      Last reviewed
      13 August 2026
      Applies to
      15.1-RELEASE, 15.0-RELEASE, 14.4-RELEASE

      Synopsis #

      A serial login and a serial system console are different facilities. A login begins after the kernel and init are running. A recovery console must also carry the earlier firmware, loader, and kernel stages that need to be diagnosed. Each stage can select a different device, speed, or console policy.

      Build the path from observed hardware and firmware behavior rather than copying a device name or I/O address. Retain a working video, provider, or hardware-management console until a cold-boot serial test has succeeded. A boot-path diagnosis can then use the last stage visible on that tested path.

      Define the required recovery boundary #

      Decide which stages must remain accessible:

      Required stageFacility that must support it
      Firmware setup and boot selectionFirmware serial redirection, a baseboard management controller, or another hardware console
      FreeBSD loader menu and promptA loader-supported UART or firmware console
      Early kernel messages and debuggerA UART selected as a kernel console
      Single-user recoveryThe active system console and the policy in /etc/ttys
      Multi-user loginAn enabled getty entry for the verified terminal line

      A serial login alone is sufficient for routine administration but not for a loader failure. Firmware redirection alone can disappear when the loader or kernel takes control.

      Identify the electrical and device path #

      Confirm the target’s hardware manual, voltage level, connector pinout, cable type, and supported bit rate. RS-232, TTL-level UARTs, and vendor-specific management headers are not electrically interchangeable. A null-modem connection and a straight-through connection also wire transmit and receive signals differently.

      A USB-to-serial adapter on the controlling computer can connect to a real UART on the target. A USB serial adapter attached to the target normally appears only after the target kernel has enumerated USB, so it cannot be assumed to carry firmware or loader output. Embedded USB device mode is another distinct arrangement and applies only to hardware and boot code that support it.

      On a running target, preserve read-only evidence:

      $ grep -i uart /var/run/dmesg.boot
      $ pciconf -lv
      # conscontrol list
      

      The uart messages identify interfaces that the running kernel attached. They do not prove that the firmware and loader can use the same interface. Device unit numbers and call-in or call-out node names are assigned from detected hardware and must not be inferred from connector labels such as COM1.

      Test the controlling terminal first #

      Connect the cable while the existing console remains available. Configure the terminal emulator for the firmware or hardware-documented speed, character size, parity, stop bits, and flow-control mode. Both 9600 and 115200 bits per second with 8 data bits, no parity, and one stop bit are common, but the initial value depends on the platform, firmware redirection, loader, and existing configuration. At the loader prompt, show comconsole_speed reports the selected loader value. Keep the controlling terminal matched to the stage being observed.

      From another FreeBSD system, cu(1) can open the detected call-out device. Replace the path and speed with values observed on that controlling system:

      # cu -l /dev/detected-callout-device -s documented-speed
      

      No output can distinguish a wrong speed, wrong cable, wrong port, absent firmware redirection, or a target that has not transmitted anything. Record which stage first produces readable output instead of changing several layers at once.

      Establish firmware and loader output #

      Enable firmware serial redirection only through the target’s documented firmware or management interface. Record the original setting and retain local console access. Some UEFI implementations already redirect the EFI console to serial; selecting an additional loader serial console can then duplicate characters.

      At the FreeBSD loader prompt, inspect the detected console before making a persistent change:

      show console
      show comconsole_speed
      

      The available console names and UART-selection variables are architecture-specific. On systems where comconsole is supported, a temporary set console=... at the loader prompt can test a serial or multiple-console selection for that boot. Use only console names documented by the installed loader(8) and loader.conf(5), and match the already verified speed.

      After a successful temporary test, place only the verified variables in /boot/loader.conf. The persistent-settings guide explains why loader settings belong there. Multiple consoles are preferable during qualification because a serial error does not simultaneously remove the video or EFI recovery path.

      Verify the kernel boundary #

      Loader output does not prove that the kernel has selected the UART. During the test boot, confirm that early kernel messages continue on serial and compare the console list after startup:

      # conscontrol list
      $ grep -i uart /var/run/dmesg.boot
      

      When the loader works but kernel output stops, inspect the installed uart(4), loader(8), and platform loader manual pages before setting hw.uart.console or port-location variables. Memory-mapped, PCI, ACPI-described, and legacy I/O UARTs use different location data. A guessed address can remove the only working console.

      Add a login only when required #

      Kernel console output does not require a serial getty. Add a login prompt only if authenticated multi-user access over the serial line is part of the design. Select the exact /etc/ttys entry that corresponds to the verified call-in terminal and use a gettytab(5) capability whose speed matches the console.

      The onifconsole flag enables a line only when it is an active kernel console. The secure flag on the selected ttyu* getty entry is a trust decision that permits direct root login on that line. It does not encrypt serial traffic or authenticate a console-server operator. For a remotely reachable console, prefer named access at the console server, strong authentication, narrow network exposure, and an insecure terminal classification unless direct root access is an explicit physical-security decision.

      The special console entry is a separate decision. Marking console as insecure causes init to request the root password before entering single-user mode; changing only the ttyu* entry does not establish that behavior. Loss of that password can then block single-user recovery. Keep an alternate console available while testing either entry and record the intended direct-login and single-user policies separately.

      After a checked /etc/ttys change, ask init to reread it without rebooting:

      # init q
      

      Confirm that ordinary console output, single-user access policy, and any intended login behave separately.

      Test recovery and rollback #

      Perform a maintenance-window test with another recovery path present:

      1. Capture firmware output from power-on.
      2. Interrupt the loader and run read-only commands.
      3. Boot once in verbose mode and confirm continuous kernel output.
      4. Boot once into single-user mode and verify the expected password policy.
      5. Complete a normal boot and test an ordinary login only if it was enabled.
      6. Repeat from a cold boot and through any remote console server or VPN used during an outage.

      Keep secrets out of terminal scrollback and console-server logs. Treat control of the serial channel as physical console access.

      If the persistent selection fails, use the retained video, EFI, management, or installation-media console to override the loader setting for one boot. Remove or correct only the added /boot/loader.conf variables and /etc/ttys entry, run init q when applicable, and repeat the temporary test. Do not rewrite boot blocks or guess UART hints as a universal recovery step.

      Primary references #

      • FreeBSD Handbook: Serial Communications
      • FreeBSD Handbook: The FreeBSD Booting Process
      • uart(4)
      • loader(8)
      • loader.conf(5)
      • ttys(5)
      • gettytab(5)
      • conscontrol(8)
      • cu(1)

      Independent documentation. Not affiliated with or endorsed by the FreeBSD Project or the FreeBSD Foundation.

      Report a bug
      • Synopsis
      • Define the required recovery boundary
      • Identify the electrical and device path
      • Test the controlling terminal first
      • Establish firmware and loader output
      • Verify the kernel boundary
      • Add a login only when required
      • Test recovery and rollback
      • Primary references