Skip to content

Instantly share code, notes, and snippets.

@yorickdowne
Last active July 8, 2026 11:53
Show Gist options
  • Select an option

  • Save yorickdowne/3cecc7b424ce241b173510e36754af47 to your computer and use it in GitHub Desktop.

Select an option

Save yorickdowne/3cecc7b424ce241b173510e36754af47 to your computer and use it in GitHub Desktop.
Debian 13 trixie upgrade

Debian 13 "Trixie"

To start, read the official release notes.

If your install fits into "vanilla Debian plus maybe a handful of 3rd-party repos", then this guide for a simple upgrade to Debian 13 "trixie" from Debian 12 "bookworm" can be helpful. 3rd-party repos are handled with a find command.

If you are on a fork of Debian such as RasPI OS, use their instructions, not this gist.

Note upgrade is only supported from Debian 12 to Debian 13. If you are on Debian 11, upgrade to Debian 12 first. Then once on Debian 12, you can upgrade to Debian 13.

From Debian 13, you can upgrade to Debian 14 after its release in summer 2027.

This guide is only for the OS itself. Applications are as plentiful as sand on the beach, and they may all require additional steps. Plan for that.

  • Check free disk space

df -h

5 GiB free is a conservative amount. sudo apt clean and sudo apt autoremove can be used to free some disk space.

On a server with only docker installed, even 1 GiB free was sufficient. Do err on the side of caution here, however.

  • Identify any 3rd-party repos that may need to be updated. They'll be changed with a find command, below.

ls /etc/apt/sources.list.d

  • Update current distribution

sudo apt update && sudo apt full-upgrade

If this brought in a new kernel, sudo reboot - otherwise continue

  • Optional: Start a screen session

So that an SSH disconnect doesn't stop your upgrade halfway through, you can run in screen:

sudo apt install -y screen && screen
  • Change old-style Debian repos to trixie, from bookworm.

sources.list might no longer be in use. If your system uses debian.sources, the next step takes care of that

sudo sed -i 's/bookworm/trixie/g' /etc/apt/sources.list

non-free has been split since Debian 12 and if used, you should also use non-free-firmware. If you are unsure, check and adjust. More complete instructions are in the Debian 12 release notes and the gist for Debian 12 upgrade

  • Change all repos in sources.list.d to trixie, from bookworm

This assumes the repos have trixie versions. Run sudo apt update after the change to trixie to confirm, and deal with any repos that aren't available in trixie.

sudo find /etc/apt/sources.list.d -type f \( -name '*.list' -o -name '*.sources' \) -exec sed -i 's/bookworm/trixie/g' {} \;

Run sudo apt update and if it fails on some repos because they don't have trixie versions, disable them for now, then test again.

  • Update Debian

For the following, say Yes to restarting services, and keep existing config files when prompted.

sudo apt update && sudo apt full-upgrade

  • If you use mdadm, stop and check EFI

Having more than one ESP (EFI System Partition) is an unusual setup. If you are certain you have only one ESP, move on to the next step.

If you have multiple ESPs for this copy of Debian, make sure they are all upgraded. Debian 13 uses grub 2.12.

  • Reboot - If you use mdadm, only proceed if you know EFI is OK

sudo reboot

  • Clean up old repos

sudo apt autoremove && sudo apt clean

  • Modernize Debian sources

Optional but recommended: Switch to deb822 format for the sources.list. This will write /etc/apt/sources.list.d/debian.sources and /etc/apt/sources.list.d/debian-backports.sources

sudo apt modernize-sources

Caveat that trixie-backports might not have a Signed-By on some 3rd-party mirrors. You can fix this by manually setting Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg in /etc/apt/sources.list.d/debian-backports.sources

  • Clean up old /tmp

Optional: Remove files from the old /tmp directory. Debian 13 replaced it with a tmpfs, see https://www.debian.org/releases/trixie/release-notes/issues.en.html#the-temporary-files-directory-tmp-is-now-stored-in-a-tmpfs

On most systems /tmp will be empty or all-but. If you did store large files here, it can be worth the effort to clean up.

sudo mkdir /mnt/tmp-chk
sudo mount --bind / /mnt/tmp-chk
ls -lha /mnt/tmp-chk/tmp/

Remove files from /mnt/tmp-chk/tmp as you see fit, then unmount again

sudo umount /mnt/tmp-chk
sudo rm -rf /mnt/tmp-chk

Automated by Ansible

Caution: This Ansible playbook does not check EFI has been updated on all disks, on an mdadm setup with multiple ESPs. Only use on machines with only one ESP, or adjust this playbook to take care of upgrading all EFI partitions.

Config ansible.cfg:

[defaults]
interpreter_python = /usr/bin/python3

Playbook trixie.yml:

---
- name: Upgrade to Debian trixie
  hosts: all
  serial: 1
  gather_facts: false
  roles:
    - base/upgrade_trixie

Role base/upgrade_trixie/tasks/main.yml:

---
- name: Get distribution version
  setup:
    filter: ansible_distribution*
- name: Skip if not Debian 12
  meta: end_host
  when: ansible_distribution != 'Debian' or ansible_distribution_major_version != '12'
- name: apt clean
  apt:
    clean: yes
  become: yes
- name: Get filesystem facts
  setup:
    filter: ansible_mounts
- name: Fail if free space on / is below 5 GiB
  ansible.builtin.assert:
    that:
      - item.size_available > (5 * 1024 * 1024 * 1024)
    fail_msg: "Free disk space on {{ item.mount }} is below 5 GiB"
  loop: "{{ ansible_mounts }}"
  when: item.mount == "/"
- name: All apt packages up to date
  apt:
    upgrade: dist
    update_cache: yes
  become: yes
- name: apt autoremove
  apt:
    autoremove: yes
  become: yes
- name: apt clean
  apt:
    clean: yes
  become: yes
- name: Check if reboot required
  ansible.builtin.stat:
    path: /run/reboot-required
    get_checksum: no
  register: reboot_required_file
- name: Reboot if required
  ansible.builtin.reboot:
    msg: "Reboot initiated by Ansible"
    connect_timeout: 5
    reboot_timeout: 600
    pre_reboot_delay: 0
    post_reboot_delay: 60
    test_command: whoami
  when: reboot_required_file.stat.exists
  become: true
- name: Switch OS from bookworm to trixie
  ansible.builtin.replace:
    path: /etc/apt/sources.list
    regexp: 'bookworm'
    replace: 'trixie'
  become: yes
- name: Find all 3rd-party repos
  ansible.builtin.find:
    paths: /etc/apt/sources.list.d
    patterns: '*'
    recurse: no
  register: third_party_repos
- name: Switch 3rd-party repos from bookworm to trixie
  ansible.builtin.replace:
    path: "{{ item.path }}"
    regexp: 'bookworm'
    replace: 'trixie'
  loop: "{{ third_party_repos.files }}"
  loop_control:
    label: "{{ item.path }}"
  become: yes
- name: Use apt to move to trixie
  apt:
    upgrade: dist
    update_cache: yes
  become: yes
- name: Get distribution version
  setup:
    filter: ansible_distribution*
- name: Fail if not Debian 13
  assert:
    that:
      - ansible_distribution_major_version == '13'
    fail_msg: "Upgrade to Debian 13 failed"
- name: apt autoremove
  apt:
    autoremove: yes
  become: yes
- name: apt clean
  apt:
    clean: yes
  become: yes
- name: Reboot on trixie
  ansible.builtin.reboot:
    msg: "Reboot initiated by Ansible"
    connect_timeout: 5
    reboot_timeout: 600
    pre_reboot_delay: 0
    post_reboot_delay: 60
    test_command: whoami
  become: yes
- name: Modernize apt sources
  ansible.builtin.command:
    cmd: apt -y modernize-sources
  become: yes
- name: Pause for 5 minutes for staggered upgrades
  pause:
    minutes: 5
@Lumipyry

Lumipyry commented Oct 9, 2024

Copy link
Copy Markdown

I can confirm that these instructions work. Thank you, @yorickdowne.

neofetch

The shell is zsh with oh-my-zsh framework and pokemon-colorscripts - if someone wonders.

I have also fully working Hyprland desktop - Installed with this wonderful automated script

@earthwlove

Copy link
Copy Markdown

Thank you!

@earthwlove

Copy link
Copy Markdown

In addition, PPA users must remove their PPA repositories before the update, or It will never happen xDD

@GhostInRags

Copy link
Copy Markdown

Good insight about PPA, earther. Trixie method 100% works, running 2 Chromebooks on her from this guide. Like a champ. I "upgraded" my media center from full blown Win 11 PC to my little HP Chromebook. A few Linux apps, Kodi, some emulators... don\t need much. And Trix does seem to make an actual difference you can "feel". Great job OP, you rock.

@yorickdowne

Copy link
Copy Markdown
Author

You guys are adventurous :). 3rd-party PPAs will work, but they might not have trixie versions yet. You can test that with sudo apt-get update, and then manually revert those repos that don't have trixie yet, back to bookworm. They should work on trixie regardless.

For example, as of today, docker-ce does not have a trixie version, yet. Some of my other PPAs do.

@yorickdowne

yorickdowne commented Feb 20, 2025

Copy link
Copy Markdown
Author

A note about locales: Some versions of the pre-release trixie updater may leave you without locales files. That's a bug. To fix this:

sudo apt-get purge locales
sudo apt install locales
sudo dpkg-reconfigure locales

And tell it to recreate all locales files.

That resolves complaints that locales files are missing.

@Louisbuitton

Copy link
Copy Markdown

I cant update now. Can you help?
https://imgur.com/a/DdV8ZE5

@yorickdowne

Copy link
Copy Markdown
Author

It tells you whatโ€™s going on: Itโ€™s a read only file system. This can happen with hardware issues or file system corruption, for example. Nothing to do with updating; fix your file system. If youโ€™re unsure how, find a Debian support group.

@marcobibichan

Copy link
Copy Markdown

After update, I cannot install neofetch, is it the problem with the source? I do not know how to fill in the apt source file.

Error: Unable to locate package neofetch

@John-Doggett

Copy link
Copy Markdown

After update, I cannot install neofetch, is it the problem with the source? I do not know how to fill in the apt source file.

Error: Unable to locate package neofetch

neofetch is EOL, install fastfetch.

@F-alling

Copy link
Copy Markdown

When Debian 13 is released August 2025
Please remove this as it is now stable

@randolf

randolf commented Jul 20, 2025

Copy link
Copy Markdown

This is helpful. Thank you for writing it up.

This full-upgrade worked (Perl, OpenVPN, etc., were upgraded perfectly), but I did run into some issues:

  1. PostgreSQL cluster failed to upgrade from 15 to 17
  2. ISC-Bind option to not replace "named.conf.default-zones" file comes up even when there's no pre-existing "named.conf.default-zones" file
  3. Apache HTTPd fails to load php8.2 module, after upgrading to php8.4 (installer didn't remove php8.2 module references?)

I hope this information is helpful to someone. Thanks to everyone who has been putting time and effort into these upgrade procedures.

@yorickdowne

yorickdowne commented Jul 20, 2025

Copy link
Copy Markdown
Author

PostgreSQL major version updates always require manual intervention, unless you use something like the auto update docker image thatโ€™s floating around.

I run my PostgreSQL in Docker and keep the tag pinned to a major version, for this reason. When itโ€™s time to move to a new version I have a homebrewed wrapper script that uses aforementioned update image once, then switches back to vanilla Postgres.

This guide is only for the OS itself. Applications are as plentiful as sand on the beach, and they may all require additional steps. Plan for that.

@yorickdowne

Copy link
Copy Markdown
Author

@F-alling Nay. Weโ€™re not even in full freeze yet, as of July 20th.

https://release.debian.org/trixie/freeze_policy.html

Anyone updating to trixie already is jumping the gun. This is fine, the thing is more stable in hard freeze than other distros are in their GA dot 1. And, itโ€™s not been promoted to stable branch, yet. It will be, MoreSoonerish. Hopefully still in August.

@jeffmcneill

Copy link
Copy Markdown

I've upgraded and got a printer problem (this is usually the case with each major Debian release). Currently the printing on a Samsung ML 1860 laserprinter does not work. Printing from Trixie to a Bookworm installation that is sharing the printer does still work, so it is not the printer driver, per se, or Samba.

@jeffmcneill

Copy link
Copy Markdown

Note also that the instructions above are great but if you have Backports in sources.list, then all updates / upgrades will fail as those repositories don't currently exist for Trixie.

@jeffmcneill

Copy link
Copy Markdown

After update, I cannot install neofetch, is it the problem with the source? I do not know how to fill in the apt source file.

Error: Unable to locate package neofetch

True, it has been removed from repositories, but is still available on git, though fastfetch is indeed also useful. https://github.com/dylanaraps/neofetch

@randolf

randolf commented Jul 21, 2025

Copy link
Copy Markdown

PostgreSQL major version updates always require manual intervention, unless you use something like the auto update docker image thatโ€™s floating around.

Yeah, and for us we have various stored procedures written in Perl, and the upgrade seems to always miss installing the newer plperl module. But it's okay, because PostgreSQL works fine before upgrading the cluster.

I run my PostgreSQL in Docker and keep the tag pinned to a major version, for this reason. When itโ€™s time to move to a new version I have a homebrewed wrapper script that uses aforementioned update image once, then switches back to vanilla Postgres.

We do similar with Podman when we need the isolation. There are dedicated systems that also run purely bare-metal, but I am liking very much what containers have to offer.

This guide is only for the OS itself. Applications are as plentiful as sand on the beach, and they may all require additional steps. Plan for that.

Thanks for pointing this out. (I also like your "applications are as plentiful as sand on the beach" metaphor.)

@0belous

0belous commented Jul 27, 2025

Copy link
Copy Markdown

Worked great and was easier than I thought
All I had to do was apt install KDE

image

@Camille-Celeste-Covarel

Copy link
Copy Markdown

Thank you <3

@vlabsc

vlabsc commented Aug 7, 2025

Copy link
Copy Markdown

Currently i use bookworm. The purpose - it's running as host that runs Kali, Parrot and Windows VMs through kvm. Using it for pen-testing, coding in rust, HTB / OSCP stuffs. once trixie becomes available, what would be the best approach to move? Upgrade or re-install? I use Dell inspiron - i7 6500 CPU, 16 GB and 2.5 TB (2 TB HDD and 512 GB SSD). Debian 12 is a dual boot along with Windows 10. Would there be anything that i have to be careful?

@HanSyt

HanSyt commented Aug 8, 2025

Copy link
Copy Markdown

@vlabsc I guess I have almost the same setup as you have, no dualboot however. Kali and Parrot in KVM, but already trixie.
I needed to install Trixie because Debian 12 had problems with my I7 150U at the time of install. So far I have no problems with it and KVM is performing a bit better than with Bookworm.
The safest option imho is reinstall everything if your system has no other value. With Dualboot I'm not sure about that. (Windows 11 is running nicely in KWM).

@Snake16547

Copy link
Copy Markdown

Worked for me with zero problems on 1x ARM and 1x AMD machine. Still waiting for a Raspbian update to come

@uplg

uplg commented Aug 9, 2025

Copy link
Copy Markdown

Worked perfectly well for me as well (on a Hetzner VPS), minor issue with the "Signed by" not detected for trixie-backports source mirrored by Hetzner in the modernize step but fixed by adding manually :
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Minor issue with nodesource as well (they didn't updated the GPG key and in 1 year it will stop working), this is tracked there : nodesource/distributions#1865

@IMR707

IMR707 commented Aug 10, 2025

Copy link
Copy Markdown

This works smoothly for my homeserver upgrade from 12 to 13 with mainly cockpit, docker and tailscale without any issue. Thanks and appreciated the share ๐Ÿ‘.

@douglarek

Copy link
Copy Markdown

Maybe you want to clean up old packages after restarting, such as old kernels: sudo apt autoremove --purge.

@telemaxx

Copy link
Copy Markdown

Worked for me, thanks for this checklist.

as mentioned by @douglarek maybe a hint howto cleanup(autoclean and autoremove)

@WingettRun

Copy link
Copy Markdown

Some 3rd party repositiories were throwing "Skipping acquire of configured file...blah blah....stable InRelease doesn't support architecture 'i386'
If you have run the modernize-sources, there is a new format for setting an architecture....the old way arch=amd64 won't work.
You must put the line such as the following in the affected sources files:

Architectures: amd64

@thegodtune

Copy link
Copy Markdown

Thank you. This worked perfectly.

@dfurmans

dfurmans commented Aug 12, 2025

Copy link
Copy Markdown

Another one

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 13 (trixie)
Release:	13
Codename:	trixie

Works like expected

The number 13 ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment