On behalf of the Starcraft team, I’m pleased to announce that Snapcraft 9.0 is available in the latest/candidate and 9.x/candidate channels. The tentative release date for the stable channel is 2026-05-19T05:00:00Z .
The major changes in Snapcraft 9 are support for core26 and the removal of core20. Users who still need to build core20 snaps should remain on the 8.x channel.
Compared to the transitions to Snapcraft 7 and 8, this release includes far fewer internal refactorings. As a result, we expect the migration from core24 to core26 to be relatively straightforward for most projects. One important exception is the the removal of Python from the core26 snap.
For a complete overview of the changes in Snapcraft 9, see the release notes .
If you have any feedback or issues, please report them here or open an issue .
Subscribed stakeholders
This section contains users who wish to be automatically notified for future releases. Reply here to be added or removed from the list.
4 Likes
dilyn
May 8, 2026, 5:36pm
2
Good work, team I look forward to parallel installing a fifth snapcraft.
1 Like
When building from this core26 branch with snapcraft 9.0, I get the following:
$ snapcraft clean && time snapcraft pack
Version has been set to '0+git.3660b5d'
Version has been set to '0+git.3660b5d'
Lint warnings:
- library: bin/ovn-nbctl: missing dependency 'libunbound.so.8'. (https://documentation.ubuntu.com/snapcraft/stable/how-to/debugging/use-the-library-linter)
- library: bin/ovn-sbctl: missing dependency 'libunbound.so.8'. (https://documentation.ubuntu.com/snapcraft/stable/how-to/debugging/use-the-library-linter)
- library: bin/ovs-vsctl: missing dependency 'libunbound.so.8'. (https://documentation.ubuntu.com/snapcraft/stable/how-to/debugging/use-the-library-linter)
Version has been set to '0+git.3660b5d'
Packed lxd_0+git.3660b5d_amd64.snap
real 27m9.451s
user 0m7.595s
sys 0m3.439s
And the libunbound.so is indeed missing from the resulting snap. When building with the older snapcraft, the lib is properly primed and there is no linter warning either.
$ snap list --all snapcraft
Name Version Rev Tracking Publisher Notes
snapcraft 8.14.5 17634 latest/candidate canonical✓ classic
snapcraft 9.0.0 18124 latest/candidate canonical✓ disabled,classic
dilyn
May 11, 2026, 2:33pm
4
Is libunbound8 in any of the {parts,stage,prime}/ directories? What plugin is the part which should be staging this using?
I had a similar sort of problem with libmalloc not being unpacked into $CRAFT_PART_INSTALL which I still haven’t resolved, maybe they’re related…
@dilyn , let me know if you can make a small reproducer or get more information.
@sdeziel , this is almost certainly a new bug in Snapcraft 9. Core26 switched to a chiseled base , so craft-parts gained support for parsing chisel manifests . This is used for determining the stage-package cutoff. It’s certainly not working as-intended in Snapcraft.
I see the core26 added wall2dpkg a few days ago, which may be an easy path forward for Snapcraft. I’ll need to root cause the current failure first.
@sdeziel , can you submit an issue in snapcraft so we can prioritize it?
1 Like
Thanks! It seems Snapcraft is working as expected (believe it or not), I followed up in the github issue with an upstream issue for core26.
1 Like
Same dependencies problem with python.
test:
plugin: nil
source: .
stage-packages:
- python3
with core26
with Snapcraft 8
Fetching stage-packages
Downloading package: python3.14
Downloading package: libffi8
Downloading package: netbase
Downloading package: readline-common
Downloading package: gcc-16-base
Downloading package: libtinfo6
Downloading package: tzdata
Downloading package: python3-minimal
Downloading package: liblzma5
Downloading package: libexpat1
Downloading package: libpython3.14-minimal
Downloading package: debconf
Downloading package: openssl-provider-legacy
Downloading package: libc-gconv-modules-extra
Downloading package: libreadline8t64
Downloading package: libdb5.3t64
Downloading package: python3
Downloading package: libzstd1
Downloading package: libc6
Downloading package: libuuid1
Downloading package: media-types
Downloading package: libpython3.14-stdlib
Downloading package: libsqlite3-0
Downloading package: libpython3-stdlib
Downloading package: libssl3t64
Downloading package: libncursesw6
Downloading package: libbz2-1.0
Downloading package: python3.14-minimal
Downloading package: zlib1g
Downloading package: libgcc-s1
with Snapcraft 9
Fetching stage-packages
Downloading package: python3
This contradicts the statement in dedicated post that nothing has to be done for snaps using python without python plugin:
Core base snaps (e.g. core22, core24) provide a run-time environment with a minimal set of libraries that are common to many applications.
Core base snaps up to and including core24 bundle the Python interpreter alongside a selection of Python libraries. But from core26 onwards, Python packages will no longer be included. This change does not affect earlier core base snaps.
The majority of application snaps that need Python already stage Python independently. These snaps will not need to be mo…
If it stays this way,
it would require:
environment:
PATH: $SNAP/usr/bin:$PATH
test:
plugin: nil
source: .
stage-packages:
- python3
- python3-minimal #required for 'python3' symlink # redundant with python3 package
- python3.14-minimal #required for python bin # redundant with python3 and python3-minimal packages
(and wouldn’t include minimal python modules as it is the case in core24)
and wouldn’t display any warning or error during build like other linters can do, if the snap is not updated.
dilyn
May 11, 2026, 9:02pm
9
I think I largely figured out what’s happening, so I think the issue is mostly a documentation one.
opened 09:01PM - 11 May 26 UTC
### What needs to get done
The uv plugin documentation should be updated to exp… lain the consequences of using certain environment variables, and potentially their workarounds (or an example snap be made to explain how to appropriately handle uv and python).
I've tested this for both core22 and core24, and both seem impacted.
I think core26+ and bare are fine, as the plugin(s) handle the interpreter differently in those cases.
### Why it needs to get done
As written, the uv plugin documentation does not adequately explain the impacts of using certain environment variables. This results in broken snaps due to unexpected behavior (at least, it's unexpected for me).
Consider the (common) case where the snap must package its own python interpreter (due to, say, a python version requirement). In this case, one must add:
```yaml
build-environment:
- UV_PYTHON: "python3.xy"
- PARTS_PYTHON_INTERPRETER: "python3.xy"
- UV_PYTHON_PREFERENCE: "only-managed"
- UV_PYTHON_DOWNLOADS: "auto"
```
This must be done to tell uv which python version to use, but also the (undocumented, at least here) `PARTS_PYTHON_INTERPRETER` must be specified as well in order for the `uv venv` command to use the correct python version and avoid errors relating to the build being unable to find the correct python in `$CRAFT_PART_INSTALL` (remove the last two lines, indeed probably your build will fail):
```bash
:: + uv venv --relocatable --allow-existing --python /usr/bin/python3.10 /root/parts/my-part/install
:: Using CPython 3.10.12 interpreter at: /usr/bin/python3.10
:: warning: The requested interpreter resolved to Python 3.10.12, which is incompatible with the project's Python requirement: `>=3.11, <4.0` (from `project.requires-python`)
:: Creating virtual environment at: /root/parts/my-part/install
:: Activate with: source /root/parts/my-part/install/bin/activate
:: + PARTS_PYTHON_VENV_INTERP_PATH=/root/parts/my-part/install/bin/python3.11
:: + uv sync --no-dev --no-editable --reinstall --extra cpu
:: Using CPython 3.11.0rc1 interpreter at: /root/parts/my-part/install/usr/bin/python3.11
:: Removed virtual environment at: /root/parts/my-part/install
:: Creating virtual environment at: /root/parts/my-part/install
:: Building immich-ml @ file:///root/parts/my-part/build/machine-learning
:: × Failed to build `immich-ml @ file:///root/parts/my-part/build/machine-learning`
:: ├─▶ Failed to identify base Python interpreter
:: ╰─▶ failed to canonicalize path `/root/parts/my-part/install/usr/bin/python3.11`: No such file or directory (os error 2)
```
https://github.com/canonical/craft-parts/blob/0910f51749eda1416b08e8389527f81e2ef8ce9f/craft_parts/plugins/uv_plugin.py#L108
However, when this is done, the venv target directory (`$CRAFT_PART_INSTALL`) is fully cleaned. This means that any `stage-packages` for this part will be unpacked, and then removed. You can see this with the minimal part:
```yaml
parts:
my-part:
plugin: uv
source: somesource
stage-packages: [hello]
build-environment:
- UV_PYTHON: "python3.xy"
- PARTS_PYTHON_INTERPRETER: "python3.xy"
- UV_PYTHON_PREFERENCE: "only-managed"
- UV_PYTHON_DOWNLOADS: "auto"
override-build: |
exit 1
```
And inspecting `$CRAFT_PART_INSTALL` (`snapcraft --debug`), then removing the `override-build` and checking again (you'll see that the previous contents of `$CRAFT_PART_INSTALL` no longer exist).
Below is a "minimal" reproducer:
```yaml
name: not-staging # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
This is my-snap's description. You have a paragraph or two to tell the
most important story about your snap. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the snap
store.
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
package-repositories:
- type: apt
ppa: deadsnakes/ppa
key-id: F23C5A6CF475977595C89F51BA6932366A755776
parts:
my-part:
plugin: uv
source: https://github.com/immich-app/immich
source-depth: 1
source-type: git
source-tag: v2.7.5
source-subdir: machine-learning
uv-extras: [cpu]
build-snaps: [astral-uv]
build-packages: [libpython3.11-dev, python3.11-dev]
stage-packages:
- gunicorn:all
- libgl1:${CRAFT_ARCH_BUILD_FOR}
- libmimalloc2.0:${CRAFT_ARCH_BUILD_FOR}
- libpython3.11:${CRAFT_ARCH_BUILD_FOR}
- python3.11:${CRAFT_ARCH_BUILD_FOR}
- python3-minimal:${CRAFT_ARCH_BUILD_FOR}
- python3.11-minimal:${CRAFT_ARCH_BUILD_FOR}
build-environment:
- UV_PYTHON: "python3.11"
- PARTS_PYTHON_INTERPRETER: "python3.11"
- UV_PYTHON_PREFERENCE: "only-managed"
- UV_PYTHON_DOWNLOADS: "auto"
```
Below is a corrected version which handles everything in the anticipated manner (following snapcraft's lead):
```yaml
name: not-staging # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
This is my-snap's description. You have a paragraph or two to tell the
most important story about your snap. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the snap
store.
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
package-repositories:
- type: apt
ppa: deadsnakes/ppa
key-id: F23C5A6CF475977595C89F51BA6932366A755776
parts:
my-part-deps:
plugin: nil
stage-packages:
- gunicorn:all
- libgl1:${CRAFT_ARCH_BUILD_FOR}
- libmimalloc2.0:${CRAFT_ARCH_BUILD_FOR}
python-libs:
plugin: nil
stage-packages:
- libpython3.11:${CRAFT_ARCH_BUILD_FOR}
- python3.11:${CRAFT_ARCH_BUILD_FOR}
- python3-minimal:${CRAFT_ARCH_BUILD_FOR}
- python3.11-minimal:${CRAFT_ARCH_BUILD_FOR}
my-part:
after: [python-libs]
plugin: uv
source: https://github.com/immich-app/immich
source-depth: 1
source-type: git
source-tag: v2.7.5
source-subdir: machine-learning
uv-extras: [cpu]
build-snaps: [astral-uv]
build-packages: [libpython3.11-dev, python3.11-dev]
build-environment:
- UV_PYTHON: "python3.11"
- PARTS_PYTHON_INTERPRETER: "python3.11"
override-build: |-
craftctl default
unlink "${CRAFT_PART_INSTALL}/bin/python"
ln -sf python3 "${CRAFT_PART_INSTALL}/bin/python"
ln -sf ../usr/bin/python3 "${CRAFT_PART_INSTALL}/bin/python3"
```
1 Like
mr_cal
May 12, 2026, 7:45am
10
@TehAppKiller , it looks like the same bug and root cause - core26 also lists the python packages in it’s manifest.
mr_cal
May 19, 2026, 11:22am
11
FYI we’ll be delaying the release of Snapcraft 9.0 to stable until this issue with core26 is resolved. A fix was landed, but hasn’t been released to core26’s stable channel yet.
mr_cal
June 11, 2026, 3:49pm
12
Hi all,
Snapcraft 9.0 has been released to latest/stable and 9.x/stable.
I’ve been able to successfully use snapcraft 9.0 stable to build my “antennas” snap. I installed it locally on Ubuntu Core 26 (on a raspberry pi 5), and everything appears to be working fine so far.
I’ll need to observe it a bit more, but core 26 appears to have also resolved a longstanding wifi firmware issue. Yay!
1 Like