Split and reassemble Debian packages with dpkg-split
You will split a trusted Debian binary package into smaller .deb parts, inspect one, reassemble the original, and understand the queue used by automatic reassembly. Allow about fifteen minutes, plus the time needed to transfer the parts. The examples use dpkg-split 1.22.6 from package dpkg 1.22.6ubuntu6.6 on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
This is a file-handling tool, not an installer. It does not install the package or update dpkg's package database. Keep the original archive until the joined file has passed your checks.
1. Check the installed command
Start with ordinary, read-only checks. No elevated privileges are needed when the archive and working directory belong to you:
$ command -v dpkg-split
/usr/bin/dpkg-split
$ dpkg-split --version
Debian 'dpkg-split' package split/join tool; version 1.22.6 (amd64).
The installed manual describes a default maximum part size of 450 KiB, where one KiB is 1024 bytes. You can select another size with --partsize, whose argument is also in KiB. Smaller parts may be useful for a constrained transfer, but they create more files to track.
Checkpoint
Identify the exact source archive and make a separate destination directory. Do not split a file in place or use a destination prefix that could overwrite an unrelated set of parts.
2. Split the complete archive
Give --split the complete binary package and, optionally, a prefix for the generated files. This example keeps the parts in parts/ and asks for a four-KiB maximum:
$ mkdir -p parts
$ dpkg-split --partsize 4 --split ./demo_1.0_all.deb parts/demo
Splitting package demo into 14 parts: 1 2 3 ... 14 done
$ ls -1 parts
demo.10of14.deb
demo.11of14.deb
demo.12of14.deb
demo.13of14.deb
demo.14of14.deb
demo.1of14.deb
demo.2of14.deb
demo.3of14.deb
demo.4of14.deb
demo.5of14.deb
demo.6of14.deb
demo.7of14.deb
demo.8of14.deb
demo.9of14.deb
The displayed count depends on the input size. Part names normally follow prefix.NofM.deb, with numbering starting at 1. If you omit the prefix, the command derives it from the complete archive name and removes a trailing .deb. The filenames are useful for humans, but they are not the identity used when joining.
Before moving the files, count them and record a digest for the original:
$ find parts -maxdepth 1 -type f -name '*.deb' -print | sort
$ sha256sum ./demo_1.0_all.deb > demo_1.0_all.deb.sha256
Do not use sudo just because the input is a Debian package. Use it only if your filesystem permissions genuinely require access, and avoid splitting archives from an untrusted source as root.
3. Inspect a part before transfer
--info reads one or more part files and prints the metadata stored in the Debian multi-part format. It is safe to use on a copy:
$ dpkg-split --info parts/demo.1of14.deb
parts/demo.1of14.deb:
Part format version: 2.1
Part of package: demo
... version: 1.0
... architecture: all
... MD5 checksum: ...
... length: ... bytes
... split every: 4096 bytes
Part number: 1/14
Exact spacing and byte counts vary. Check the package name, version, architecture, part number and total part count. The companion deb-split(5) description says that the archive contains a debian-split header followed by the corresponding raw data member. Readers must accept additional header lines when the minor format version grows, but a changed major version is incompatible.
Transfer all parts as binary files. A text-mode transfer or an incomplete copy can leave a file that looks plausible but cannot be reassembled.
4. Join a complete set manually
On the receiving machine, put every part in one directory and use --join. Set an explicit output name so the result does not accidentally replace a useful file:
$ dpkg-split --join --output ./demo-rejoined.deb parts/demo.*of14.deb
Putting package demo together from 14 parts: 1 2 3 ... 14 done
$ sha256sum ./demo-rejoined.deb
918eaf950659b901159ce39b31fb2fb808c61b3467ae38380c51c66007b39829 demo-rejoined.deb
$ sha256sum --check demo_1.0_all.deb.sha256
./demo_1.0_all.deb: OK
The arguments must contain every part of exactly one original binary file, with each part listed once. They do not need to be in numerical order, and their filenames do not need to match the names produced by the split operation. They do need to have been made with the same part size and compatible metadata. The default output name, when --output is omitted, is based on the package name, version and architecture.
Safety warning
--output can replace an existing file. Choose a new name or make a backup first. If the join fails, remove only the incomplete new output after checking the error; keep the original archive and all parts.
5. Queue parts for automatic reassembly
--auto is useful when parts arrive one at a time. It stores received parts in a depot and creates the output only when the complete set is present. The --output option is mandatory because the caller must know where the completed archive will appear.
Use a private depot for a normal user test:
$ mkdir -p ./parts-queue
$ dpkg-split --auto --depotdir ./parts-queue --output ./demo-auto.deb parts/demo.11of14.deb
Part 11 of package demo filed (still want 1, 2, 3, ... and 14).
$ dpkg-split --listq --depotdir ./parts-queue
Packages not yet reassembled:
Package demo-something: part(s) 11 (total ... bytes)
The package name and missing-part list are examples of the shape of the output, not fixed text. Repeat the command for each received part. When the last missing part arrives, the command joins the package and writes demo-auto.deb. A successfully queued part still gives exit status 0; the output file is the useful distinction between waiting and complete.
For a production receiver, choose the depot deliberately and restrict its permissions. The default depot is /var/lib/dpkg/parts, which is part of the system's dpkg administration area. Automatic accumulation and discarding are privileged operations with security consequences. Never delegate them to an untrusted user, and do not feed untrusted package parts to a root-owned workflow.
6. Recover from missing or unwanted parts
If --listq shows a package still waiting, compare the reported part numbers with the files you received. --info can confirm that a file belongs to the expected package, but it cannot repair a missing or corrupted transfer.
To remove queued parts for a named package, pass that package name to --discard. With no package argument it clears the entire selected depot:
$ dpkg-split --discard --depotdir ./parts-queue demo
$ dpkg-split --listq --depotdir ./parts-queue
Discarding is irreversible for the depot contents. It does not delete your copies of the original archive or transferred parts elsewhere, so those are the recovery path. Confirm the package name and depot before using the no-argument form.
7. Check failures without guessing
Exit status 0 means the requested operation succeeded. Status 1 is specific to --auto and means the supplied file was not a binary package part. Status 2 covers invalid usage, a part that appears corrupted, and system errors such as access or allocation failures. Capture the status immediately after the command:
$ dpkg-split --auto --depotdir ./parts-queue --output ./demo-auto.deb ./received-part.deb
$ status=$?
$ printf 'dpkg-split status: %s\n' "$status"
dpkg-split status: 0
If a manual join fails, first check that every part is present exactly once, then inspect the parts with --info. Do not fix a mismatch by renaming files or changing the part size. If the archive is untrusted or appears malformed, stop and verify its source instead of trying the operation as root.
Done means
- The installed
dpkg-splitversion and the source archive are known. - Every generated part has been transferred as binary data and accounted for.
--infoshows matching package metadata and a complete part range.- The joined archive matches the original checksum, or the automatic output has been checked against a trusted digest.
- Any queue is private, deliberately located and empty or documented after recovery.
- No untrusted split archive was examined, joined or queued as root.