Skip to content

fix: Linux deb/rpm installs fail in-app updates with "invalid updater binary format"Fix/linux deb updater feed - #3123

Merged
kev1n77 merged 3 commits into
GCWing:mainfrom
EthanCheung-gh:fix/linux-deb-updater-feed
Sep 20, 2026
Merged

kev1n77 merged 3 commits into
GCWing:mainfrom
EthanCheung-gh:fix/linux-deb-updater-feed

Conversation

@EthanCheung-gh

Copy link
Copy Markdown
Contributor

Fixes #3118

Summary

On Linux clients installed from the .deb package, every in-app update fails with
invalid updater binary format. The update feed (latest-v1.json) maps linux-*
platform keys to the AppImage asset only, while tauri-plugin-updater requires a
.deb payload for deb installs (and .rpm for rpm installs).

Environment

  • open-bit-fun 1.0.0 → 1.0.1, amd64 deb install (/usr/bin/openbitfun-desktop, dpkg-owned)
  • Ubuntu (GNOME/Wayland), tauri-plugin-updater 2.10.1 (per Cargo.lock)

Evidence

  1. Update download + signature verification succeed; the staged payload in
    ~/.cache/<app>/app-updates/ is a raw AppImage (\x7fELF + AI\x02 magic).
    pending.json signature comment confirms: file:OpenBitFun_1.0.1_amd64.AppImage.
  2. Plugin decides the installer from the current bundle type, then validates payload:
    install_deb() → infer::archive::is_deb(bytes) fails → Error::InvalidUpdaterFormat
    ("invalid updater binary format").
  3. Root cause in the release pipeline:
    • scripts/generate-tauri-latest-json.mjs: isUpdaterBundle() whitelist
      (.appimage/.app.tar.gz/.tar.gz/.zip/.exe) excludes .deb; inferPlatform()
      has no deb branch. So linux-x86_64 can only ever point at the AppImage.
    • scripts/collect-tauri-updater-assets.mjs collects AppImage-only naming.
  4. The v1.0.1 release already ships OpenBitFun_1.0.1_amd64.deb + .deb.sig
    (and *.rpm + .rpm.sig) — the signed artifacts exist; only the manifest
    pipeline drops them.

Impact

Every deb/rpm-installed Linux user gets this error on each in-app update.
AppImage installs are unaffected. Workaround: manual apt install ./OpenBitFun_*_amd64.deb.

Suggested fix (Option A, recommended)

  • Emit bundle-type-aware platform keys in latest-v1.json:
    linux-<arch> → AppImage, plus linux-<arch>-deb / linux-<arch>-rpm.
  • Client: updater_platform_key() (src/apps/desktop/src/api/system_api.rs) appends
    the -deb/-rpm suffix per detected bundle type (APPIMAGE env / dpkg / rpm ownership).
  • Extend collect-tauri-updater-assets.mjs to collect + rename the signed deb/rpm assets
    and mirror-sync them.
  • Alternative: endpoint template latest-{{bundle_type}}-v1.json (plugin-native
    {{bundle_type}} substitution) — needs per-type manifests on both origins.

Regression test

Extend scripts/tauri-release-manifest.test.mjs to require the deb/rpm platform keys,
plus a unit test that generate-tauri-latest-json.mjs maps
OpenBitFun_<ver>_amd64.deb(.sig) → linux-x86_64-deb with signature.

@GCWing
GCWing requested a review from kev1n77 September 20, 2026 00:53
@kev1n77

kev1n77 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the fix. The bundle-specific updater changes look correct.

Before merging, please:

  • Rebase onto the latest main and resolve the test conflict, preserving both macOS and Linux cases.
  • Run CI, as no checks are currently reported.
  • Verify updates using real .deb and .rpm installations, and confirm AppImage still works.

After these are addressed, this should be ready for another review.

…talls

tauri-plugin-updater selects its Linux installer from the running bundle
type and rejects every other payload with 'invalid updater binary
format': deb installs require a .deb payload, rpm installs require an
.rpm. The release pipeline already signs deb/rpm packages, but
generate-tauri-latest-json.mjs and collect-tauri-updater-assets.mjs
filtered them out, so latest-v1.json could only ever point
linux-x86_64/linux-aarch64 at the AppImage and every deb/rpm install
failed each in-app update.

Collect and map signed .deb/.rpm artifacts into dedicated
linux-<arch>-deb / linux-<arch>-rpm manifest keys. The renamed copies
embed the platform key, so they cannot collide with the raw bundler
packages staged separately.
… gate

REQUIRED_UPDATER_PLATFORMS now demands linux-{x86_64,aarch64}-deb and
-rpm entries, so a release whose signed deb/rpm updater artifacts go
missing fails loudly instead of silently shipping a feed that breaks
deb and rpm installs again.
The desktop updater probes latest-v1.json with a bare linux-<arch> key,
so a deb (or rpm) install ranked endpoints against the AppImage payload
and then tauri-plugin-updater rejected the download with 'invalid
updater binary format' at install time.

Derive the manifest key suffix from the same
tauri::utils::platform::bundle_type() the plugin uses to pick its
installer: deb installs request linux-<arch>-deb, rpm installs request
linux-<arch>-rpm, every other bundle type keeps the bare key.
@EthanCheung-gh
EthanCheung-gh force-pushed the fix/linux-deb-updater-feed branch from 2895af8 to 3544d9f Compare September 20, 2026 09:00
@EthanCheung-gh

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main (e0b8ae60d) and force-pushed (23b870e60, 1206c77dc, 3544d9f31).

Test conflict: resolved in scripts/tauri-release-manifest.test.mjs by keeping both sides — the macOS .dmg manual-installer cases from main and the Linux bundle-type cases from this PR. Full suite green: node --test scripts/tauri-release-manifest.test.mjs → 9 passed / 0 failed. Client-side: cargo test -p openbitfun-desktop --lib updater_platform_key → 2 passed (new per-install-form suffix selection + the existing key-convention test). pnpm run check:github-config green with the workflow change.

CI: the rebase push re-triggers ci.yml (pull_request → main, scripts/** not path-ignored). Fork PRs sit in "awaiting approval" until a maintainer approves the workflow run — that's why no checks were reported before; approving it should surface the results.

Real-package verification (all three Linux bundles built from this branch):

  • .AppImage — launches from the built artifact: startup banner, first-run state initialization, clean shutdown, no errors in the app log.
  • .deb — packaging is untouched by this PR (it only changes release feed scripts and the updater's manifest-key selection in system_api.rs); debs from this same build pipeline installed cleanly via dpkg on Ubuntu 26.04 during development, and the extracted package initializes correctly with an isolated data root. A full in-app update run (1.0.1 deb → next release) is only possible once a release carrying the new feed keys is published — and 1206c77dc now makes the packaging gate refuse any feed missing the bundle-type Linux keys, so the failure mode this PR fixes cannot ship silently.
  • .rpm — the bundle builds (OpenBitFun-1.0.1-1.x86_64.rpm); no rpm-based host or container on this machine for an install smoke test. Happy to run one if there's a CI lane for it; otherwise an rpm install check at release time covers it.

Local artifacts for reference: deb 137,297,150 B (601ff79c…), rpm 137,083,301 B (ba9f0626…), AppImage 217,594,360 B (bde98d01…).

@kev1n77
kev1n77 merged commit b5dfe2e into GCWing:main Sep 20, 2026
15 checks passed
@EthanCheung-gh
EthanCheung-gh deleted the fix/linux-deb-updater-feed branch September 20, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Desktop in-app update fails with "invalid updater binary format" on deb/rpm-installed Linux clients (update feed serves AppImage only)

2 participants