Summary
charmcraft pack with the uv plugin and a cross-arch platforms: entry (host arch != target arch) succeeds without error and emits a .charm whose manifest.yaml declares the target architecture, but whose Python venv contains compiled wheels (.so files) built for the host architecture. The artifact is silently corrupt and will fail at import on a host of the declared architecture.
Environment
- charmcraft: 4.2.1 (snap,
latest/candidate)
- LXD: 5.21.4-aee7e08 (rev 38767,
5.21/stable)
- host arch:
x86_64
Reproduction
charmcraft.yaml:
type: charm
platforms:
ubuntu-24.04-amd64:
build-on: [ubuntu@24.04:amd64]
build-for: [ubuntu@24.04:amd64]
ubuntu-24.04-arm64:
build-on: [ubuntu@24.04:amd64]
build-for: [ubuntu@24.04:arm64]
parts:
charm:
plugin: uv
source: .
build-snaps: [astral-uv]
build-packages: [git]
pyproject.toml pulls in any wheel-bearing dependency, e.g. cryptography, pydantic, pyyaml.
$ charmcraft pack --platform ubuntu-24.04-arm64 -v
...
Packed microceph_ubuntu-24.04-arm64.charm
No warning. No error.
Observed
$ unzip -p microceph_ubuntu-24.04-arm64.charm manifest.yaml | head -7
charmcraft-version: 4.2.1
charmcraft-started-at: '2026-05-06T18:48:24.634836'
bases:
- name: ubuntu
channel: '24.04'
architectures:
- arm64
$ unzip -l microceph_ubuntu-24.04-arm64.charm | grep -E '\.so'
... venv/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust.abi3.so
... venv/lib/python3.12/site-packages/pydantic_core/_pydantic_core.cpython-312-x86_64-linux-gnu.so
... venv/lib/python3.12/site-packages/yaml/_yaml.cpython-312-x86_64-linux-gnu.so
... (etc.)
$ unzip -p microceph_ubuntu-24.04-arm64.charm \
venv/lib/python3.12/site-packages/cryptography/hazmat/bindings/_rust.abi3.so > /tmp/r.so
$ file /tmp/r.so
/tmp/r.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), ...
Same for pydantic_core: x86-64 ELF inside an artifact tagged arm64. Filenames carrying *-x86_64-linux-gnu.so survive in the venv.
Expected
One of:
- Fail the pack.
uv plugin (or charmcraft itself) detects target arch != build host arch with no functioning cross-resolve and aborts with a clear error directing the user to a native runner. This is the safe default — silent mislabeling is the worst failure mode.
- Cross-resolve wheels.
uv plugin invokes uv with --python-platform <target> so manylinux wheels for the target architecture are downloaded and staged. (Source-only deps would still need a real cross-toolchain, which is out of scope; but the common manylinux case is solvable.)
Workaround in use
charmcraft.yaml is restricted to build-on == build-for entries. Non-amd64 publishes are gated on per-arch native self-hosted runners.
Summary
charmcraft packwith theuvplugin and a cross-archplatforms:entry (host arch!=target arch) succeeds without error and emits a.charmwhosemanifest.yamldeclares the target architecture, but whose Python venv contains compiled wheels (.sofiles) built for the host architecture. The artifact is silently corrupt and will fail at import on a host of the declared architecture.Environment
latest/candidate)5.21/stable)x86_64Reproduction
charmcraft.yaml:pyproject.tomlpulls in any wheel-bearing dependency, e.g.cryptography,pydantic,pyyaml.No warning. No error.
Observed
Same for
pydantic_core: x86-64 ELF inside an artifact taggedarm64. Filenames carrying*-x86_64-linux-gnu.sosurvive in the venv.Expected
One of:
uvplugin (or charmcraft itself) detects target arch!=build host arch with no functioning cross-resolve and aborts with a clear error directing the user to a native runner. This is the safe default — silent mislabeling is the worst failure mode.uvplugin invokesuvwith--python-platform <target>so manylinux wheels for the target architecture are downloaded and staged. (Source-only deps would still need a real cross-toolchain, which is out of scope; but the common manylinux case is solvable.)Workaround in use
charmcraft.yamlis restricted tobuild-on == build-forentries. Non-amd64 publishes are gated on per-arch native self-hosted runners.