Upgrading to Oracle Linux 10 with Leapp

Upgrading to Oracle Linux 10 with Leapp: Methods, Best Practices & Drawbacks



📅 July 12, 2026
🏷️ Oracle Linux, Leap upgrade,  OCI ⏱ 25 min read

 Article Overview

Moving a fleet from Oracle Linux 9 to Oracle Linux 10 no longer means rebuilding every host. The leapp utility performs a controlled, in-place major-version upgrade that keeps your operating system, database, and application stack in place. This guide walks through how Leapp works, the four deployment methods available, a complete command-by-command upgrade with copy-ready scripts, an Ansible pattern for fleet rollouts, and an honest look at the limitations, blockers, and known issues you need to plan around before touching production.

1. What the Leapp Utility Actually Does

Leapp is not a glorified dnf update. A plain package-manager run cannot cross a major release boundary, because the package inventory, module streams, default kernel, and several configuration formats all change between Oracle Linux 9 and 10. Attempt it directly and you are left with a half-migrated, frequently unbootable machine.

Instead, Leapp runs a framework of small inspection-and-transformation units. It takes a full inventory of the running system, models the entire package transaction in advance, flags anything that would break, blocks the run until you resolve the serious findings, and only then rebuilds the machine inside a dedicated upgrade boot environment. The design goal is that risk surfaces before the upgrade rather than during it.



2. The Supported Upgrade Path

Leapp advances a host exactly one major release at a time, and each hop relies on its own version-specific tooling package. There is no supported shortcut that jumps straight from OL8 (or OL7) to OL10 — you climb the ladder one rung per run, validating along the way.



A few fixed rules define what OL10 expects at the finish line:

  • UEK Release 8 is the floor. Hosts on UEK R7 are carried up to R8; the Red Hat Compatible Kernel path is supported too.
  • Both architectures are covered — x86_64 and 64-bit Arm (aarch64), on-premises and on Oracle Cloud Infrastructure.
  • Only Oracle-signed packages are guaranteed. Software from third-party repositories may be dropped from the transaction or left behind as stale .el9 packages, and Oracle makes no stability promise for it.

3. The Two-Phase Workflow

Every Leapp upgrade is split into an assessment you can run safely any number of times, and a one-way transformation you run once. Treat the boundary between them as a gate: nothing proceeds while the assessment still lists blocking problems.



he preupgrade phase only reads the system. It produces a risk report plus an answer file that captures decisions Leapp needs you to confirm. The upgrade phase does the real work: it stages a special boot image, and after you reboot, the package transaction runs automatically during startup. From that reboot until the OL10 login prompt appears, you leave the machine alone — interrupting the boot-time transaction can leave it unbootable.

4. Four Deployment Methods

The methods differ mainly in where the OL10 packages come from and how the host is managed. Rather than spelling out every repository by hand, Leapp offers convenience switches that enable the correct set automatically.

🌐 Standard in-place--oraclelinux

For on-premises servers and generic VMs that can reach public yum.oracle.com or a local mirror. Enables the BaseOS, AppStream, and UEK R8 repositories for you.

☁️ OCI instance--oci

For instances running in Oracle Cloud Infrastructure. It is a superset of the standard switch, additionally pulling in the Ksplice and OCI-included repositories.

💽 Isolated / air-gapped--iso <path>

For hosts with no route to any repository. Packages come from a mounted OL10 ISO only. Use this sparingly — see the caution below.

🛠️ Managed fleetOS Management Hub

For estates administered centrally, where the Leapp run is orchestrated through Oracle's management service rather than driven host by host.

MethodSwitchBest whenRepositories enabled
Standard in-place--oraclelinuxOn-prem / VMs with mirror or public repo accessBaseOS, AppStream, UEK R8
OCI instance--ociOracle Cloud Infrastructure instancesAbove + Ksplice + OCI-included
Isolated--iso <path>No repository connectivity at allMounted ISO only
Managed fleetOS Management HubCentrally managed estatesOrchestrated by the service

⚠️ A caution on the ISO method

On some customised builds, an ISO will not carry every package your host needs, so packages can quietly go missing from the transaction. Reserve --iso for genuinely disconnected environments where a local mirror or the public repositories simply cannot be reached.

One optional repository is worth calling out: the developer-oriented ol10_codeready_builder is off by default. If your workload depends on build tooling such as rpcgen, python3-pyxattr, or various -devel packages, add --enablerepo ol10_codeready_builder to the command, or Leapp will warn that those packages cannot be located.

5. Preparing the System

Most upgrades that fail were actually let down at the preparation stage. Clear these before you run anything.

Start from a clean, current OL9 baseline

prepare-baseline.sh
# Confirm you are on OL9 and not booted into a debug kernel
cat /etc/oracle-release
uname -r

# The upgrade requires this locale
sudo localectl set-locale LANG=en_US.UTF-8

# Patch to the latest OL9, then reboot so you upgrade from a current base
sudo dnf -y update
sudo reboot

Give /boot enough headroom

OL10 wants at least 1 GB on /boot (2 GB is comfortable), with roughly 320 MB free to stage the incoming kernels, initramfs, and crash-dump images. This is noticeably more than earlier releases asked for, and a cramped /boot is one of the most common reasons a run stops before it starts.

check-boot-space.sh
df -h /boot
# If it is tight, prune superseded kernels first:
sudo dnf remove $(dnf repoquery --installonly --latest-limit=-1 -q)

Two more items that catch people out

  • Unregister from ULN. If the host is tied to the Unbreakable Linux Network or a ULN mirror, unregister it first so Leapp resolves against the right repositories.
  • Capture a real rollback point. Leapp has no built-in reverse gear. Snapshot the boot volume (OCI) or the VM / LVM volumes (on-prem). This snapshot is your only clean way back.

6. Step-by-Step Upgrade (with Code)

Below is a full manual run for a standard on-prem OL9 → OL10 upgrade. Drive it from a console or out-of-band session — an iLO/iDRAC console, the OCI console connection, or a VNC session — never from the SSH session you are about to reboot out from under.

ol9-to-ol10-upgrade.sh
# ── Step 0 · Record a baseline for later comparison ─────────
cat /etc/oracle-release
uname -r
rpm -qa | sort > /root/pkglist-pre-upgrade.txt

# ── Step 1 · Install the OL9→OL10 Leapp tooling ─────────────
# Clear any leftover tooling from a previous hop, then install fresh
sudo dnf remove -y leapp leapp-upgrade 2>/dev/null || true
sudo dnf install -y leapp-upgrade

# ── Step 2 · Run the read-only assessment ───────────────────
sudo leapp preupgrade --oraclelinux
# Add the developer repo only if your stack needs it:
# sudo leapp preupgrade --oraclelinux --enablerepo ol10_codeready_builder

# ── Step 3 · Read the report and fix what it flags ──────────
sudo less /var/log/leapp/leapp-report.txt
# Machine-readable version for ticketing / automation:
sudo jq '.entries[] | {title, severity}' /var/log/leapp/leapp-report.json

Each finding is graded high, medium, or low. A high-severity item serious enough to break the upgrade is additionally marked an inhibitor — Leapp refuses to continue until you clear it.



Some inhibitors are decisions rather than defects — Leapp asks you to acknowledge them explicitly in the answer file:

answer-and-upgrade.sh
# ── Step 4 · Confirm required answers, then re-check ────────
# Example: acknowledge a specific verification the report asked about
sudo leapp answer --section check_vdo.no_vdo_devices=True --add
sudo leapp preupgrade --oraclelinux   # repeat until the report is clean

# ── Step 5 · Run the upgrade (no inhibitors remaining) ──────
sudo leapp upgrade --oraclelinux

# ── Step 6 · Reboot into the upgrade boot image ────────────
sudo reboot
# WATCH THE CONSOLE. The host boots a temporary image, runs the
# full transaction automatically, and reboots again. Do NOT
# interrupt it. Wait for the OL10 login prompt.

Once the machine comes up on OL10, validate and re-harden. Leapp deliberately relaxes SELinux to permissive during the transaction, so restoring enforcing mode is on you.

post-upgrade.sh
# ── Step 7 · Verify, harden, and clean up ──────────────────
cat /etc/oracle-release          # expect: release 10.x
uname -r                         # expect: an el10 / UEK R8 kernel

# Return SELinux to enforcing
sudo setenforce 1
sudo sed -i 's/^SELINUX=permissive/SELINUX=enforcing/' /etc/selinux/config
getenforce                       # expect: Enforcing

# Find residual el9 packages that were not carried over
rpm -qa | grep -E '\.el9' | sort > /root/residual-el9.txt
# Review the list, install OL10 equivalents from yum.oracle.com,
# then remove whatever genuinely remains.

# Re-apply your crypto policy and archive the logs for audit
sudo update-crypto-policies --set DEFAULT
sudo cp -r /var/log/leapp /root/leapp-upgrade-$(date +%Y%m%d)

7. Automating Across a Fleet

For more than a handful of hosts, wrap the same flow in a playbook. The critical design choice is a hard gate: a host must never reach leapp upgrade while its assessment still reports inhibitors. This playbook assesses first, fails loudly if any blocker remains, and only upgrades when you explicitly ask it to.

leapp-ol10.yml
---
- name: Oracle Linux 9 to 10 Leapp upgrade
  hosts: ol9_targets
  become: true
  serial: 1                      # one host at a time — keep the blast radius small
  vars:
    do_upgrade: false           # default to assessment-only

  tasks:
    - name: Confirm the host is on OL9
      ansible.builtin.command: grep -qi 'release 9' /etc/oracle-release
      changed_when: false

    - name: Set locale and bring OL9 fully current
      ansible.builtin.shell: |
        localectl set-locale LANG=en_US.UTF-8
        dnf -y update
      register: patched
      changed_when: "'Nothing to do' not in patched.stdout"

    - name: Reboot into the patched baseline
      ansible.builtin.reboot:
      when: patched.changed

    - name: Install the OL9 to OL10 tooling
      ansible.builtin.dnf:
        name: leapp-upgrade
        state: latest

    - name: Run the assessment
      ansible.builtin.command: leapp preupgrade --oraclelinux
      register: pre
      failed_when: false        # inhibitors return non-zero; handled below
      changed_when: false

    - name: Load the machine-readable report
      ansible.builtin.slurp:
        src: /var/log/leapp/leapp-report.json
      register: report_raw

    - name: Stop if any inhibitor remains
      vars:
        report: "{{ report_raw.content | b64decode | from_json }}"
        inhibitors: >-
          {{ report.entries
             | selectattr('flags', 'defined')
             | selectattr('flags', 'contains', 'inhibitor')
             | list }}
      ansible.builtin.fail:
        msg: "{{ inventory_hostname }} still has {{ inhibitors | length }} inhibitor(s)."
      when: inhibitors | length > 0

    - name: Perform the upgrade (gated)
      ansible.builtin.command: leapp upgrade --oraclelinux
      when: do_upgrade | bool

    - name: Reboot to apply the OL10 transaction
      ansible.builtin.reboot:
        reboot_timeout: 3600     # the boot-time transaction is slow; be patient
      when: do_upgrade | bool

    - name: Confirm we landed on OL10
      ansible.builtin.command: grep -qi 'release 10' /etc/oracle-release
      changed_when: false
      when: do_upgrade | bool

Run it in two passes. The first — ansible-playbook leapp-ol10.yml — assesses and gates. Fix whatever it surfaces, then run ansible-playbook leapp-ol10.yml -e do_upgrade=true. The serial: 1 setting upgrades one node at a time, so a bad batch can never take down a whole tier at once.

8. Best Practices

🧪 Rehearse on a clone

Snapshot a representative host, upgrade the copy, and test your applications on OL10 before touching anything real. The report finds OS-level risk, not how your app behaves on a new kernel and library set.

📋 Work the report to zero

Treat every high and inhibitor entry as a task with a remediation hint attached. Clear them all, re-run the assessment, and only move on when it is clean.

🖥️ Drive from a console

The run reboots twice and executes a long automatic transaction. If you are on the SSH session that dies at reboot, you go blind exactly when you most need eyes on the box.

💾 Snapshot for rollback

There is no undo. A boot-volume or VM snapshot is the difference between a five-minute recovery and a rebuild.

🕐 Fix /boot and the clock first

A cramped /boot and a system clock running behind the repository build date (which triggers signature-validation errors) are two of the most common — and most avoidable — failures.

🌊 Upgrade in waves

Never big-bang a fleet. One node, validate, then widen. Keep an inventory diff of packages before and after so nothing from a third-party repo slips through unnoticed.

9. Drawbacks & Known Issues

In-place upgrades are convenient, not free. Know these before you commit.

🚫 Hard blocker with no workaround

A system using Btrfs in a RAID configuration cannot be upgraded. The assessment flags it as an inhibitor and offers no remedy — the run simply halts. If you use Btrfs, check this first.

Blockers you can work around

  • LUKS-encrypted partitions inhibit the run.
  • High-availability cluster configurations inhibit the run.
  • Network-mounted filesystems (NFS, iSCSI) are unsupported during the upgrade — unmount them, comment out their /etc/fstab entries, upgrade, then restore.

Silent traps to watch for

  • Several NICs sharing the kernel NIC's prefix (for example, multiple eth* interfaces) can cause the host to lose network connectivity after the upgrade because of interface renaming.
  • NetworkManager may fail to start on first boot after the upgrade, tied to a name-resolution service failure.
  • XFS filesystems missing the bigtime feature are flagged — they remain exposed to the year-2038 timestamp overflow. It is not a blocker, but enable bigtime while still on OL9.
  • Residual .el9 packages from unsupported or developer repositories may not upgrade and will linger without updates, which security scanners will flag.

✅ Where in-place shines

  • Preserves a hand-tuned host — OS, database, and app stack stay put
  • No reinstall, re-licensing, or full reconfiguration
  • Repeatable and gated, so risk surfaces before the change
  • Same flow on-prem and on OCI, across x86_64 and Arm

❌ What you accept in return

  • No rollback — recovery means restoring a snapshot
  • A long, uninterruptible reboot window during the transaction
  • SELinux left permissive and some OL9-era config left in place
  • Single-hop only — no jumping straight from OL8 to OL10

10. In-Place Upgrade vs. Rebuild

Leapp is not always the right answer. For hosts that are already defined as code, a clean OL10 build plus a configuration and data migration is often the lower-risk path.



ConsiderationIn-place LeappRebuild on OL10
Host is defined as code / statelessOverkillBest fit
Hand-tuned, stateful "pet" serverBest fitCostly to reproduce
Unresolvable inhibitor presentNot possibleClean path
Preserve existing host identity & configPreservedRebuilt
Long uninterruptible reboot tolerableRequiredNot applicable
Want a pristine hardened baselineCarries driftFresh start

11. Summary & Next Steps

✅ Key Takeaways

• Leapp turns OL9 → OL10 into a repeatable, gated, in-place change: assess, clear every inhibitor, confirm the answer file, then upgrade and reboot into an automatic transaction.

• The method you choose — --oraclelinux, --oci, --iso, or a managed-fleet flow — mostly comes down to where your packages live.

• The discipline is the same everywhere: patch to a clean baseline, snapshot for rollback, drive from a console, respect the report, and roll out in waves.

• Know the blockers up front — Btrfs-on-RAID has no remedy, and there is no built-in rollback.

Recommended next steps

  • Run leapp preupgrade against a representative host today and read the report end to end — it is free intelligence about your estate.
  • Inventory third-party and developer-repo packages so you have OL10 replacements lined up before you cut over.
  • Rehearse the whole flow on a clone, validate your applications on OL10, then schedule the first production wave.
  • Keep an archived copy of /var/log/leapp per host for audit and troubleshooting.
  • Cross-check the current Oracle Linux 10: Upgrading Systems With Leapp manual for your exact minor release, since repository names, requirements, and known issues are refreshed over time.
SZ

Syed Zaheer

Service Delivery Director · Techvisions · Cloud, AI & Managed Infrastructure

Syed Zaheer is an author, speaker, and technology enthusiast with deep expertise across the Oracle landscape — databases, middleware, applications, AI, and cloud infrastructure. He contributes to the Oracle community through technical articles, conference talks, and knowledge-sharing that help organizations modernize and optimize their enterprise platforms.


Comments

Popular posts from this blog

EBS R12.2 Install Error - oracle.apps.fnd.txk.config.ProcessStateException: Patch directory does not exist or not writable -

Installation of Oracle Applications R12.1.1 on Linux and vmware

ntp service in Maintenance mode Solaris 10