What Is a DEB File? Read the First Bytes, Then Open the Package Inside
A DEB file is a Debian software package: an ar archive that bundles a program with the notes an installer needs. Jump to your question below, or work through it in order.
What Is a DEB File? A Debian software package, made of three parts in a fixed order
Short answer
DEB files are Debian software packages: ar archives that bundle the files of a program with the notes an installer needs. Debian, Ubuntu, Linux Mint and many other Linux systems use them. Inside are three parts in a fixed order: version file, control archive and data archive.
You can spot a DEB file by its first bytes. They spell !<arch>, then a line feed. In our tests, dpkg-deb and dpkg -i handled all 10 good DEB files with content. 7-Zip opened 6 of the 10, and it could not open DEB files with zstd inside.
To find your kind of DEB file, read the first-byte check. To look inside one, read how to open DEB files. To add one to your system, read the install steps. If your DEB file is damaged, start with the damage tests.
Every DEB file bundles the files of a program with a control file that names the package, its version and what it needs. Linux installers read them with dpkg or apt.
Picture a program you want on Ubuntu that your software center does not list. The maker gives you a file named like hello_1.0-1_amd64.deb. You open it, and your system adds a program, its settings and help pages in the right folders. That file is a DEB file.
FileInfo calls .deb a Debian Software Package made by the Debian Project, and it files the ending under compressed files. It says DEB files install or update applications on Debian Linux and variants like Ubuntu.
Wikipedia says the format changed in Debian 0.93. Before that, a DEB file was a short header followed by two gzip archives. From 0.93 on, it is an ar archive. The deb(5) manual page gives the current rules.
The ending also reaches past normal installers. Wikipedia names udeb, the micro deb used by the Debian installer, and says Ipkg and Opkg use a similar .ipk format. Our tests cover normal .deb files only.
DEB file facts at a glance
| Property | Value |
|---|---|
| File extension | .deb, and .udeb for the installer variant |
| Usual meaning | Software packages for Debian and systems built on it |
| Type | Binary files in the ar archive layout |
| Media type |
application/. The names x-debian-package and x-deb are deprecated, says deb(5).
|
| Made by | The Debian Project |
| Starts with |
The text !<arch> and a line feed
|
| Parts | debian-binary, control.tar and data.tar, in that order |
| Compression | None, gzip, xz or zstd for control. Those and bzip2 or lzma for data. |
| Opens in | dpkg-deb, ar with tar, 7-Zip and archive managers |
| Safe to open | Reading is low risk. Installing a DEB file calls its scripts as root, so install only packages you trust. |
Wrong page? Linux programs stored as bare files use the ELF format, and the ELF file guide covers them. Windows installers end in .msi, and the MSI file guide explains those. Mac disk images end in .dmg, and the DMG file guide covers them.
Which Kind of DEB File Is Yours? The first bytes and the member names name the kind
Read the first eight bytes and the member names of your DEB file. Modern DEB files start with !<arch> and a line feed. Old ones start with the text 0.939000. Anything else is another format or a damaged copy.
You need no special software. The short script below prints first bytes, kind and members of your DEB file. It also unpacks the compressed members and reads the control file. Save it as check_deb.py and give it the name of your DEB file.
import bz2, gzip, io, lzma, os, sys, tarfile
path = sys.argv[1]
size = os.path.getsize(path)
f = open(path, "rb")
head = f.read(8)
print("First 8 bytes:", " ".join("%02x" % b for b in head))
if head == b"!<arch>\n":
kind = "ar archive, the modern DEB layout"
elif head[:7] == b"!<arch>" and head[7:8] == b"\r":
kind = "ar magic with CR LF: a text-mode transfer broke it"
elif head == b"0.939000":
kind = "old DEB format (version 0.939000)"
elif not any(head):
kind = "zero bytes where the magic should be"
else:
kind = "not a DEB"
print("Kind:", kind)
print("Size on disk: {:,} bytes".format(size))
problems = []
if kind.startswith("ar archive"):
pos, names = 8, []
while pos + 60 <= size:
f.seek(pos)
h = f.read(60)
name, n = h[:16].decode("latin-1").strip().rstrip("/"), int(h[48:58])
names.append(name)
if h[58:60] != b"`\n" or pos + 60 + n > size:
problems.append("member %s goes past the end of the file or has a bad header" % name)
break
data = f.read(n)
if name == "debian-binary":
print("debian-binary says:", data.decode().strip())
if not data.startswith(b"2."):
problems.append("format version is not 2.x")
try:
raw = data
if name.endswith(".gz"): raw = gzip.decompress(data)
elif name.endswith(".xz"): raw = lzma.decompress(data)
elif name.endswith(".bz2"): raw = bz2.decompress(data)
elif name.endswith(".lzma"): raw = lzma.decompress(data, format=lzma.FORMAT_ALONE)
if name.startswith("control.tar") and not name.endswith(".zst"):
tar = tarfile.open(fileobj=io.BytesIO(raw))
text = tar.extractfile(tar.getmember("./control")).read().decode()
if "Package:" not in text:
problems.append("the control file has no Package line")
except Exception as e:
problems.append("member %s does not unpack: %s" % (name, e))
pos += 60 + n + (n & 1)
print("Members:", ", ".join(names))
if not names or names[0] != "debian-binary":
problems.append("debian-binary is not the first member")
c = [i for i, x in enumerate(names) if x.startswith("control.tar")]
d = [i for i, x in enumerate(names) if x.startswith("data.tar")]
if not c or not d or c[0] > d[0]:
problems.append("control.tar must come before data.tar")
elif kind.startswith("old DEB"):
print("dpkg-deb reads this layout. ar and 7-Zip do not.")
else:
problems.append("not an ar archive")
print("Problems:", "; ".join(problems) if problems else "none found")
python check_deb.py g03-xz.deb
First 8 bytes: 21 3c 61 72 63 68 3e 0a
Kind: ar archive, the modern DEB layout
Size on disk: 202,396 bytes
debian-binary says: 2.0
Members: debian-binary, control.tar.xz, data.tar.xz
Problems: none found
We tried the script on all 11 good DEB files and all 15 damaged ones. It found no problem in the 11 good files, and it flagged 12 of the 15 damaged ones. It reads zstd members only as far as their names, because Python has no zstd reader built in. The three it missed are in the section on damaged files.
python check_deb.py d08-data-xz-bitflip.deb
First 8 bytes: 21 3c 61 72 63 68 3e 0a
Kind: ar archive, the modern DEB layout
Size on disk: 202,396 bytes
debian-binary says: 2.0
Members: debian-binary, control.tar.xz, data.tar.xz
Problems: member data.tar.xz does not unpack: Corrupt input data
| Kind | Where to look | What you see |
|---|---|---|
| Modern DEB | Bytes 0 to 7 |
The text !<arch> and a line feed
|
| Old DEB | Bytes 0 to 7 | The text 0.939000 |
| RPM | Bytes 0 to 3 |
ed ab ee db
|
| Gzip file | Bytes 0 and 1 |
1f 8b
|
| ZIP file | Bytes 0 to 3 |
50 4b 03 04
|
| Wiped start | Bytes 0 to 7 | Zero bytes only |
Inside the ar layout, a 60-byte header comes before every member. The first header starts at byte 8, and debian-binary starts at byte 68. In every modern DEB file we built, that text was 2.0 and a line feed.
Three more clues about your DEB file
What Is Inside DEB Files? A version file, control archive and data archive
DEB files store three ar members in a fixed order: debian-binary, then control.tar and then data.tar. They give a version, package notes and then the files. Installers read them in that order.
Think of a parcel and its packing slip. The slip names contents, and the box has goods. The control archive is the slip, the data archive is the box and the version file is a label on the outside.
| Part | Position | What it has |
|---|---|---|
| Magic | Bytes 0 to 7 |
The text !<arch> and a line feed
|
| Member header | 60 bytes before every member | Name, date, owner, group, mode and size |
| debian-binary | Byte 68 in our files | The text 2.0 and a line feed |
| control.tar | After debian-binary | The control file, md5sums and scripts |
| data.tar | After control.tar | The files, with paths from the root |
| Extra members | After data.tar | Ignored today, says deb(5) |
Every member starts with a header of 60 bytes. It stores the name in 16 bytes, then the date, owner, group, mode and size as text, and it ends with two marker bytes. The size field has 10 digits, so a member can reach about 9.3 GiB. Names are limited to 15 characters, says deb(5) member rules.
What the control archive stores
The control archive is a small tar file. Its control file is required. The other files are optional, and our scripts DEB file used five of them.
| File | What it does |
|---|---|
| control | Names the package, version, processor type, maintainer and description |
| md5sums | Lists an MD5 hash for every file in the data archive |
| conffiles | Names the settings files that removal keeps |
| preinst, postinst, prerm, postrm | Scripts the installer calls around installs and removals |
| triggers, shlibs, symbols | Optional files for libraries and shared events |
Compression inside DEB files
The control and data archives are tar files, and they can be compressed. deb(5) compression list allows none, gzip, xz and zstd for the control archive. It adds bzip2 and lzma for the data archive. The ending of the member names the choice, like data.tar.xz.
| Compression | Ending | What we saw |
|---|---|---|
| gzip | .gz | Built, read and installed |
| xz | .xz | Built, read and installed |
| zstd | .zst | Built, read and installed. 7-Zip could not open it. |
| None | .tar | Built, read and installed |
| bzip2 | .bz2 | Repacked by hand, then read and installed |
| lzma | .lzma | Repacked by hand, then read and installed |
Our dpkg-deb 1.22.6 on Ubuntu 24.04 built zstd by default. The Debian manual page for dpkg-deb(1) says xz is the default, so your system may differ. We could not build bzip2 or lzma DEB files. dpkg-deb stopped with this message: "dpkg-deb: error: obsolete compression type 'bzip2'; use xz or gzip instead". So we repacked the data member of a gzip DEB file to make them.
Old DEB files
Before Debian 0.93, packages were not ar archives. deb-old(5) says the file starts with the version text 0.939000 and a line with the size of the first part. Two gzip archives follow. We built one with dpkg-deb and the option --deb-format=0.939000. dpkg-deb read it and dpkg -i installed it.
The other readers struggled. ar said file format not recognized. 7-Zip opened the old file as a gzip file and gave back only the control part. The file command said only data.
Version and extra members
deb(5) extra-member rules say programs should ignore members after data.tar. It also says they should accept a higher minor version, like 2.5, and stop on a new major version. We tested all three. A member named _extra after data.tar.gz changed nothing. Version 2.5 worked everywhere. Version 3.0 stopped dpkg-deb with this message: "archive is format version 3.0; get a newer dpkg-deb".
What Do 26 Test DEB Files Show? 11 good packages, 15 damaged copies and four readers
We tested 26 DEB files: 11 good ones we built and 15 damaged copies. Both dpkg-deb and dpkg -i handled all 10 good DEB files with content. The ar tool with tar handled 9, and 7-Zip handled 6.
We found no public set of DEB files with known content to test, so we built our own with dpkg-deb 1.22.6 on Ubuntu 24.04. Every DEB file got the same 4 files: a script, a settings file, a binary file of 200,000 random bytes and a short README with accents and Japanese text.
Then we damaged copies in 15 ways and tried four readers on all 26: dpkg-deb, dpkg -i, ar with tar and 7-Zip 23.01. Files counted as returned only when their SHA-256 hash matched the original. We built and tested everything in October 2026.
We did not test packages from the Debian or Ubuntu archives, signed packages, graphical installers or DEB files bigger than 6 MB. We also skipped the udeb and ipk variants, and every archive tool except 7-Zip. We found no DEB viewer from SysTools or Freeviewer, so this guide has no tool cards.
The 11 good DEB files we built
| DEB file | What it has and tests |
|---|---|
| Default | Zstd inside, the default on our machine. 201,356 bytes. |
| gzip | Gzip in both archives. 201,504 bytes. |
| xz | Xz in both archives. 202,396 bytes. |
| zstd | Zstd chosen by hand. 201,350 bytes. |
| No compression | Both archives left uncompressed. 225,472 bytes. |
| bzip2 data | Data archive repacked with bzip2. 202,788 bytes. |
| lzma data | Data archive repacked with lzma. 203,936 bytes. |
| With scripts | Xz, plus postinst and prerm scripts and a conffiles list. 202,480 bytes. |
| Big | Zstd, with 6,000,000 random bytes. 6,001,502 bytes. |
| Old format | Built with --deb-format=0.939000. 201,336 bytes. |
| Empty | No files at all, only control data. 582 bytes. |
The 4 files are hello-test with 39 bytes, hello-test.conf, README and photo.bin. dpkg-deb returned all 4, byte for byte, from the 10 DEB files with content. The empty DEB file installed and left no files, as it should.
| Reader | DEB files read | Note |
|---|---|---|
| dpkg-deb -x | 10 of 10 | Every compression, and the old format |
| dpkg -i | 10 of 10 | photo.bin matched after every install |
| ar with tar | 9 of 10 | Failed only on the old format |
| 7-Zip | 6 of 10 | Two or three passes. No zstd, no old format. |
7-Zip drills in by itself on some DEB files. On gzip and xz DEB files it unpacked the data member on the first pass and showed data.tar, so the control archive stayed hidden. On bzip2 and lzma DEB files it showed all three members, and the data archive needed two more passes. On zstd DEB files it saved control.tar.zst and data.tar.zst, and the next pass failed with exit code 2.
The 15 damaged DEB files
We damaged copies of the good DEB files in 15 ways, with one kind of damage in every file. Four were cut or emptied, 7 hit the ar wrapper and 4 hit the control or data archives. The damage section lists all 15 with the fix. The table counts the DEB files that gave back all 4 test files.
| Damage (files) | Before repair | After repair |
|---|---|---|
| Cut or emptied (4) | 1 | 1 |
| ar wrapper (7) | 5 | 7 |
| Inside the archives (4) | 2 | 2 |
| All 15 DEB files | 8 | 10 |
Before repair means at least one reader returned all 4 files with no change to the DEB file. Only 2 files gained: the zeroed start and the text-mode transfer. The other repairs made dpkg itself accept the DEB file. That matters, because dpkg -i installed only 3 of the 15 as they were and 10 of 15 after repair.
Five stayed incomplete. Three were damaged copies: one cut in half, one with a zeroed second half and one with a flipped byte in xz data. One was an uncompressed DEB file with a flipped byte. The last was the empty file, which had nothing to restore.
Read the counts with care. We damaged small DEB files with simple breaks. Downloads that fail, disks that fail and bad mirrors do messier harm. The numbers show how these tools behave with these DEB files, and they are not rates for all DEB files.
What Does Our Expert Say About DEB Files? A note from Neeraj Singh on checking packages before you install
Look at the first bytes and member names before you install a DEB file, and check the md5sums list when the source is new to you. Installing calls the package scripts as root, and a flipped byte inside an uncompressed DEB file passes every reader without a warning.
Expert insight
“A DEB file looks like one file, but it is three parts in a fixed order. Look at the first eight bytes and the member names before you install it. In our 15 damaged test files, one flipped byte inside an uncompressed DEB file passed dpkg-deb, 7-Zip and dpkg -i with no error. Only the md5sums check found it. Install DEB files from sources you trust, because the scripts inside get root rights.”
Why a quiet result can still be wrong
dpkg-deb, 7-Zip, ar with tar and dpkg -i all finished without an error on the package with one flipped byte inside photo.bin. Every one returned photo.bin at its full size of 200,000 bytes. Only a hash comparison showed the change.
The reason is the layout. An uncompressed tar archive has no checksum of its own. Gzip and xz store a check value, so the same flip inside a compressed member did stop the readers. They said "incorrect data check" for gzip and "compressed data is corrupt" for xz.
The md5sums file closes the gap. It lists an MD5 hash for every file in the package. Extract the files and the control data, then check them with md5sum -c. The verify section shows the steps.
Our script missed 3 of 15 damaged files. Two were harmless: the version 2.5 file and the file with an extra member. Every reader accepted both, as deb(5) guidance says they should. The third was a flipped byte inside a tar, which no wrapper check can find.
Keep the original. Work on a copy of the DEB file, and keep the first hash. If a repair goes wrong, you can start again. Compare the hash with the one on the download page, if there is one.
How Do You Open DEB Files? dpkg-deb, ar with tar or 7-Zip, with nothing installed
Open DEB files with dpkg-deb, with ar and tar or with 7-Zip. dpkg-deb read all 10 test DEB files with content. 7-Zip read 6, and it cannot open packages with zstd inside. Save the files to a folder, so nothing gets installed.
DEB files have no viewer of their own, and a double click may start an installer. If you only want to look inside, use a program that unpacks archives. The table lists what we tried and what we only read about.
| Program | What it does | What we saw |
|---|---|---|
| dpkg-deb | The Debian package program for Linux | 10 of 10 DEB files |
| ar with tar | Basic Linux tools that split and open the parts | 9 of 10 DEB files |
| 7-Zip | Free archiver, listed by FileInfo for Windows | 6 of 10 DEB files |
| dpkg -i | Installs the package | 10 of 10 DEB files |
| Archive managers | FileInfo lists File Viewer Plus, IZArc, PeaZip and B1 Free Archiver | Not tested |
| Package managers | FileInfo lists Synaptic for Linux and Cydia for iOS | Not tested |
Open DEB files with dpkg-deb
This is the program made for the job. Option -I prints the control data. Option -c lists the files. Option -x saves them to a folder, option -e saves the control files and option -R saves both. None of them installs anything. The dpkg-deb manual page lists every option.
dpkg-deb -I g02-gzip.deb
dpkg-deb -c g02-gzip.deb
dpkg-deb -x g02-gzip.deb files
dpkg-deb -e g02-gzip.deb control
dpkg-deb -R g02-gzip.deb both
dpkg-deb -I g02-gzip.deb
new Debian package, version 2.0.
size 201504 bytes: control archive=486 bytes.
21 bytes, 1 lines conffiles
210 bytes, 8 lines control
234 bytes, 4 lines md5sums
Package: g02-gzip
Version: 1.0-1
Architecture: all
Maintainer: Test Maker <test@example.invalid>
Description: Test package g02-gzip
Our dpkg-deb -c listed 16 entries for the test DEB file: 4 files, a link and 11 folders. It worked on all 11 good DEB files, the old format and the empty package too.
Open DEB files with ar and tar
Without dpkg you can still split a package. The command ar x saves three members into the current folder. Then tar opens the archives, and it spots gzip, xz, bzip2, lzma and zstd by itself. This worked on 9 of 10 DEB files. The old format is the one that failed.
mkdir out && cd out
ar x ../g02-gzip.deb
tar -xf data.tar.*
mkdir control && tar -xf control.tar.* -C control
Using tar on the DEB file itself does not work. GNU tar said "This does not look like a tar archive".
Open DEB files with 7-Zip
Install 7-Zip, then open your DEB file as an archive, or use the command line. A DEB file has archives inside an archive, so plan on two or three passes.
7z l g02-gzip.deb
7z x g02-gzip.deb -oout1
7z x out1/data.tar -oout2
On gzip and xz DEB files the first pass gave data.tar. On DEB files with no compression it gave control.tar and data.tar. On bzip2 and lzma DEB files it gave all three members, and the data archive needed two more passes. On the three zstd DEB files it saved the two members and the next pass failed with exit code 2. For those, use dpkg-deb or ar with tar.
Reference pages
These four links open outside pages: the deb(5) format page, the dpkg-deb page, Wikipedia and FileInfo.
dpkg-deb manual page
Every option for listing, extracting and building
A tip for Windows and Mac users. We tested on Linux only. Opening a DEB file on Windows or macOS shows the files, and they are meant for Debian-based systems. For other installers, see the guide to MSI installers and the guide to DMG disk images.
How Do You Install a DEB File? apt install, dpkg -i and what happens to dependencies
Install DEB files with sudo apt install ./file.deb, which also fetches missing dependencies. Use sudo dpkg -i file.deb when the dependencies are ready. Installing calls the package scripts as root, so install DEB files from sources you trust.
Installing is different from opening. An install copies files to system folders, saves a package record and calls the scripts from the control archive. The two usual commands are apt install and dpkg -i.
- Check the DEB file first with dpkg-deb -I. Read its name, version, architecture and Depends line.
- Install it with sudo apt install ./file.deb. The ./ matters, because without it apt looks for a package of that name in its lists.
- Or use sudo dpkg -i file.deb when you have the dependencies ready. If one is missing, dpkg stops and leaves the package unconfigured.
- List what it added with dpkg -L, and remove it with dpkg -r or dpkg -P.
dpkg-deb -I g14-needs-tree.deb
sudo apt install ./g14-needs-tree.deb
# or, when the dependencies are already in place
sudo dpkg -i g14-needs-tree.deb
dpkg -L g14-needs-tree
sudo dpkg -r g14-needs-tree
sudo dpkg -P g14-needs-tree
| Test | What we saw |
|---|---|
| dpkg -i on 11 packages | All installed. photo.bin matched the original after every install. |
| dpkg -i, missing dependency | It unpacked the package, then stopped. dpkg -s showed "install ok unpacked". |
| apt install, simulated, dependency in the archive | It planned to add tree, then our package. |
| apt install, simulated, no such dependency | It stopped with an unmet dependencies list. |
| Scripts | dpkg -i called our postinst, and dpkg -r called our prerm. |
| dpkg -r, then dpkg -P | Removal kept our settings file. Purging deleted it. |
When a dependency is missing
The control file can name other packages the program needs. We built a DEB file that needs a package that does not exist. dpkg -i unpacked it, printed the message below and left it unconfigured. When apt meets a package left like that, it suggests apt --fix-broken install.
sudo dpkg -i g12-deps.deb
dpkg: dependency problems prevent configuration of g12-deps:
g12-deps depends on g12-missing-lib (>= 1.0); however:
Package g12-missing-lib is not installed.
dpkg: error processing package g12-deps (--install):
dependency problems - leaving unconfigured
With apt the dependency is fetched for you, if the archive has it. We built a second DEB file that needs tree. A simulated install planned to add tree first and our DEB file second. Without the ./ in front of the name, apt said "Unable to locate package". We only simulated apt, so no package changed.
apt-get install --simulate ./g14-needs-tree.deb
Inst tree (2.1.1-2ubuntu3.24.04.2 Ubuntu:24.04/noble-updates [amd64])
Inst g14-needs-tree (1.0-1 local-deb [all])
Conf tree (2.1.1-2ubuntu3.24.04.2 Ubuntu:24.04/noble-updates [amd64])
Conf g14-needs-tree (1.0-1 local-deb [all])
What dpkg -r and dpkg -P leave behind
The dpkg manual page says removal keeps the settings files named in conffiles, and purging removes them. We saw both. After dpkg -r, /etc/hello-test.conf was still there. After dpkg -P, it was gone.
Why installing needs care
The scripts in the control archive are programs. The dpkg manual page lists prerm, preinst and configuring among the steps of an install. In our test, the postinst printed a line as root. A bad DEB file could do far more.
Install DEB files from the Debian or Ubuntu archives, or from a maker you know. To read scripts first, save the control files with dpkg-deb -e and open postinst and the others in a text editor.
What we did not test. Our machine was a throwaway container, and we simulated apt installs. We did not test graphical installers, double clicks or downgrades.
How Do You Make a DEB File With dpkg-deb? A folder, a control file and one command
Make DEB files by putting your files in a folder, adding a DEBIAN/control file and calling dpkg-deb --build with --root-owner-group. Choose gzip, xz or zstd with -Z. Our dpkg-deb 1.22.6 refused to build bzip2 or lzma.
You need three things: the folder tree as it should appear on the target system, a DEBIAN folder and a control file. Our dpkg-deb refused to build without a Package, a Version or an Architecture line. Without a Maintainer or Description it built the DEB file and printed a warning.
- Make a folder named for the package, and copy your files into it with the paths they should have on the target system.
- Add a DEBIAN folder with a control file. Add md5sums, conffiles and scripts if you need them.
- Build with dpkg-deb --root-owner-group --build, the folder name and the new file name.
- Check the result with dpkg-deb -I and -c, then test an install on a machine you can reset.
Package: hello-test
Version: 1.0-1
Section: misc
Priority: optional
Architecture: all
Maintainer: Test Maker <test@example.invalid>
Description: A small test package
A longer line starts with one space.
mkdir -p hello/DEBIAN hello/usr/bin
cp hello-test hello/usr/bin/
nano hello/DEBIAN/control
dpkg-deb --root-owner-group --build hello hello_1.0-1_all.deb
dpkg-deb -I hello_1.0-1_all.deb
Mind the owner. Without --root-owner-group, our dpkg-deb stored our own user name as the owner of every file. The listing from dpkg-deb -c showed ubuntu/ubuntu. With the option, it showed root/root.
Choose a compression
The option -Z picks the compression. We built the same folder with every choice. Our files are mostly 200,000 random bytes, which no compressor can shrink, so the sizes are close. Text and programs usually shrink more, so test your own files.
| Option | Size | Result |
|---|---|---|
| -Zgzip | 201,504 bytes | Built |
| -Zxz | 202,396 bytes | Built |
| -Zzstd | 201,350 bytes | Built |
| -Znone | 225,472 bytes | Built. control.tar was 10,240 bytes. |
| -Zbzip2 | None | Refused: obsolete compression type |
| -Zlzma | None | Refused: obsolete compression type |
The same input gives the same file
We set SOURCE_DATE_EPOCH to one fixed number and built the same folder twice, with a pause of 2 seconds between the builds. The two DEB files had the same SHA-256 hash. That is how we made our test files repeatable.
Make an old format DEB file
Our dpkg-deb 1.22.6 can still write the old layout. Add the option --deb-format=0.939000. We used it for the old-format sample, and dpkg-deb read and installed the result. New DEB files should use the modern layout, because ar and 7-Zip cannot read the old one.
dpkg-deb --root-owner-group --deb-format=0.939000 --build hello hello_old.deb
How Do You Check a DEB File Is Sound? The md5sums list, dpkg -V and a download hash
DEB files have an md5sums list, so you can check every file inside without installing. Save the files from your DEB file, then check them with md5sum -c. After an install, dpkg -V compares the files on disk with the list dpkg saved.
The md5sums file lists an MD5 hash for every file the package installs. dpkg-deb -e saves it and md5sum -c reads it. This checks the files against the package's own list. It cannot show that someone changed both file and list, so also compare the hash of the entire DEB file with the one on the download page.
- Save the control files with dpkg-deb -e and the data files with dpkg-deb -x.
- Go into the data folder and check the files with md5sum -c.
- After you install, use dpkg -V to compare the installed files with the list dpkg saved.
- Hash the DEB file itself with sha256sum and compare it with the number on the download page.
dpkg-deb -e g02-gzip.deb control
dpkg-deb -x g02-gzip.deb files
cd files
md5sum -c ../control/md5sums
# after you install it
dpkg -V g02-gzip
sha256sum g02-gzip.deb
md5sum -c ../control/md5sums
etc/hello-test.conf: OK
usr/bin/hello-test: OK
usr/share/doc/g05-none/README: OK
usr/share/g05-none/photo.bin: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
| Check | What we found |
|---|---|
| md5sum -c on a good package | All 4 files said OK. |
| md5sum -c on the flipped-byte package | photo.bin said FAILED. The other 3 said OK. |
| dpkg -V after we changed one byte | It printed ??5?????? beside photo.bin. |
| lintian on our test package | It called out a missing changelog, copyright file and manual page. |
The ??5?????? line means the MD5 hash differs. The dpkg(1) page on verifying says the check uses data stored in the dpkg database. So it compares installed files with the list dpkg saved, and not with the DEB file. Lintian is a checker for package makers, and our bare test DEB files had no changelog or copyright file.
Signatures
Wikipedia lists debsigs, debsig-verify and dpkg-sig as tools that sign and check DEB files. We did not test them. For a DEB file from a web page, the hash on that page is the check you have.
Which hash to use. MD5 finds accidents, but it is weak against a deliberate change. Use the SHA-256 hash from the download page for the file itself.
Why Will Your DEB File Not Open? Fifteen damage tests, and fixes that took one command
DEB files that will not open usually have a damaged wrapper: the magic, the version, the member order or the size field. In our 15 damaged files, 7 needed one small repair, 2 needed none, 7-Zip read 1 cut file in full and 5 stayed incomplete.
We broke copies of the good DEB files in 15 ways and tried four readers before and after a repair. The chart shows what the readers could do. Green means all 4 test files came back byte for byte, amber means some did and red means none did.
| Damage | What you see | Fix |
|---|---|---|
| First 8 bytes zeroed | is not a Debian format archive | Write the magic back |
| Version text says 3.0 | archive is format version 3.0; get a newer dpkg-deb | Write 2.0 back |
| Members in the wrong order | premature member data.tar.gz before control.tar | Pack them in order |
| Line feeds became CR LF | corrupted by being downloaded in ASCII mode | Change CR LF to LF |
| Size field too big | Unexpected end of archive | Set the true size |
| Control archive damaged | incorrect data check | Write a new control file |
| No Package line | missing 'Package' field | Add the line |
| Cut or zeroed data | compressed data is corrupt | Keep what unpacks |
| Empty file | unexpected end of file in archive magic | Download again |
The repairs, one command per fix
Every repair writes a few bytes back or packs the same parts again. Always do it on copies. The option conv=notrunc matters. Without it, dd cuts a file after the bytes it writes and destroys the rest. Four of these repairs gave a file identical to the original, byte for byte: the magic, version, CR LF change and size field.
# magic gone: write it back
printf '!<arch>\n' | dd of=broken.deb bs=1 count=8 conv=notrunc
# version text wrong: it starts at byte 68
printf '2.0' | dd of=broken.deb bs=1 seek=68 count=3 conv=notrunc
# members in the wrong order: unpack, then pack in order
ar x broken.deb
ar rc fixed.deb debian-binary control.tar.* data.tar.*
# CR LF damage from a text-mode transfer
python3 -c "d=open('broken.deb','rb').read(); open('fixed.deb','wb').write(d.replace(b'\r\n', b'\n'))"
The size field needs a few more lines. This script reads every header and fixes any size that goes past the end of the file. On our file with a size field 5,000 bytes too big, it gave back the original, byte for byte.
import sys
b = open(sys.argv[1], "rb").read()
pos, out = 8, b[:8]
while pos + 60 <= len(b):
h = bytearray(b[pos:pos + 60])
n = int(h[48:58])
if pos + 60 + n > len(b):
n = len(b) - pos - 60
h[48:58] = str(n).ljust(10).encode()
out += bytes(h) + b[pos + 60:pos + 60 + n]
pos += 60 + n + (n & 1)
open(sys.argv[2], "wb").write(out)
A damaged control archive costs more. The files in the data archive are fine, so you can save them with dpkg-deb -x and write a new control file. The rebuilt DEB file installed, but it had lost the md5sums list, conffiles list and any scripts from the old control archive. A control file that only lacks a line is easier, because dpkg-deb -R saves the other parts too.
# control file damaged: save the files, then write a new control file
mkdir fixed && dpkg-deb -x broken.deb fixed
mkdir fixed/DEBIAN && nano fixed/DEBIAN/control
dpkg-deb --root-owner-group --build fixed fixed.deb
# control file missing a line: save everything, edit it, build again
dpkg-deb -R broken.deb fixed
nano fixed/DEBIAN/control
dpkg-deb --root-owner-group --build fixed fixed.deb
What the tools could not fix
Downloads cause two of these. A text-mode transfer adds a CR before every line feed, and dpkg even names the cause: "corrupted by being downloaded in ASCII mode". A download that reserved the full size with zeros and stopped part way can give a zeroed half. Download again in binary mode and compare the hash.
Compare before you celebrate. After a repair, use dpkg-deb -I and dpkg-deb -c, then check the files with the md5sums list if the DEB file still has one. A DEB file that installs is not always a DEB file that matches the original.
How Do You Convert a DEB File to RPM or TAR? alien, dpkg-deb and the scripts that get left behind
Convert DEB files to RPM or TAR with alien, or take the files out with dpkg-deb --fsys-tarfile. alien drops the scripts unless you add --scripts. Test a converted package on a machine you can reset.
Wikipedia lists alien as a program that converts DEB files and other packages to and from other formats. We tried it on our scripts DEB file. The option --to-rpm made an RPM file, and the option --to-tgz made a tarball. The table shows what the routes kept.
| Route | What we saw |
|---|---|
| alien --to-rpm | Made an RPM file. The file command called it "RPM v3.0 bin noarch", and it starts with ed ab ee db. |
| alien --to-tgz | Made a tarball of 200,879 bytes with the files and the link. |
| dpkg-deb --fsys-tarfile | Wrote the data archive as a tar stream with 16 entries. |
| Scripts | Left out by default. With --scripts the RPM listed a postinstall and a preuninstall scriptlet, and the tarball added install/doinst.sh and install/predelete.sh. |
| Settings file | The RPM listed /etc/hello-test.conf as a config file. |
sudo alien --to-rpm --scripts g08-scripts.deb
sudo alien --to-tgz --scripts g08-scripts.deb
dpkg-deb --fsys-tarfile g08-scripts.deb > files.tar
rpm -qp --scripts g08-scripts-1.0-2.noarch.rpm
A converted package is not a native one. Dependencies and library names may differ between systems. We checked only that the files and the scripts came across. We did not install the RPM on a Red Hat system.
Change the compression of a DEB file
You can also pack the same files again. Save them with dpkg-deb -R, then build with another -Z choice. We built gzip, xz, zstd and uncompressed DEB files from one folder, and the sizes are in the make section. The deb(5) note on zstd says zstd needs dpkg 1.21.18 or newer, so choose gzip or xz when you share a DEB file with older systems.
Check after converting. List the result with rpm -qlp or tar -tzf, and compare the names with dpkg-deb -c. A route that finishes without an error has not proved that every file came across.
What Else Uses the DEB Ending? udeb, ipk and look-alike packages
The .deb ending names Debian packages. The nearby endings .udeb and .ipk use similar layouts for other jobs, and RPM files do the same job on other Linux systems. Read the first bytes before you choose a program.
FileInfo's page for .deb lists one meaning: the Debian Software Package. It also names .udeb as a related micro deb format with only the essential files, and it treats that as a separate extension.
The Wikipedia entry describes udeb as a stripped-down variant used by the Debian installer. It also says Ipkg and Opkg use a similar .ipk format. We built and tested neither, so we cannot say how their bytes differ from a normal DEB file.
| Kind | Used for | Note |
|---|---|---|
| DEB | Debian, Ubuntu, Linux Mint and others |
Starts with !<arch>
|
| UDEB | The Debian installer | Stripped down, says Wikipedia. Not tested. |
| IPK | Ipkg and Opkg systems | Similar layout, says Wikipedia. Not tested. |
| RPM | Other Linux systems |
Starts with ed ab ee db. Tested with alien.
|
| TAR.GZ | Source code and general archives |
Starts with 1f 8b
|
How to separate them
Read the first eight bytes. The text !<arch> followed by the members debian-binary, control.tar and data.tar means a DEB file. If you see something else, the table of starts lists the other starts we know.
Files inside a DEB file
The files inside are often programs in ELF format, and the ELF program format guide explains how those look. Our test programs were small scripts, so we did not test ELF files. Archives that are not packages are covered in the ZIP archive guide and the RAR archive guide.
What Is the DEB File Format Made Of? The facts we could check, and what we left out
The DEB format is documented. These are facts we could check against the deb(5) manual page, Wikipedia, FileInfo and our own 26 DEB files, plus points we left out.
| Item | What we could check |
|---|---|
| Name | Debian binary package, format 2.0. FileInfo calls it a Debian Software Package. |
| Extension | .deb, and .udeb for installer packages, says Wikipedia |
| Maker | The Debian Project, says FileInfo |
| Status | Documented in the deb(5) manual page. The old layout is in deb-old(5). |
| Container | An ar archive. Only the common ar format is supported, with no long-name extension, says deb(5). |
| Starts with |
The text !<arch> and a line feed at byte 0
|
| Members | debian-binary, control.tar and data.tar, in that order |
| Version | debian-binary says 2.0 and a line feed. A higher minor version is accepted. |
| Compression | Control: none, gzip, xz or zstd. Data: those plus bzip2 or lzma. Says deb(5). |
| Limits | Member names up to 15 characters. Sizes of 10 digits, about 9,536 MiB. Says deb(5). |
| Extra members | Ignored after data.tar. Future members that can be skipped start with an underscore. Says deb(5). |
| Media type |
application/ |
| Old layout | Starts with 0.939000, then two gzip archives. Used before Debian 0.93. |
About the values we list
The magic, version text and byte positions come from our own DEB files, built by dpkg-deb 1.22.6 in October 2026. Other versions may choose other compression by default. The file dates in our DEB files read 2026-09-21, because we fixed SOURCE_DATE_EPOCH so the builds repeat.
What we left out
We did not test packages from the Debian or Ubuntu archives, signed packages, graphical installers or DEB files over 6 MB. We did not test macOS, Windows or phone tools. Our 7-Zip tests were done on Linux.
We found no DEB viewer from SysTools or Freeviewer, so we name none and show no tool cards. We name no prices. What we say about udeb and ipk comes from Wikipedia and FileInfo, and what we say about Windows programs comes from FileInfo.
Our damage tests are simple breaks in a small set of DEB files. We tried four readers, and others may behave differently. The numbers in this guide show how those readers behaved, and they are not rates for all DEB files.
Sources checked
For the format rules, see the manual page for deb(5) and the deb-old(5) manual page. For options, see the manual page for dpkg-deb and the manual page for dpkg. For history and variants, see the Wikipedia article on the DEB format. For the programs FileInfo lists, see the FileInfo entry for .deb.
Every test count came from the 26 DEB files and the scripts in our research folder.
Frequently Asked Questions About DEB Files
What is a DEB file?
It is a Debian software package: an ar archive that bundles the files of a program with a control file. Debian, Ubuntu, Linux Mint and many other Linux systems install programs from DEB files with dpkg or apt. The first bytes spell !<arch> and a line feed. FileInfo lists it as a Debian Software Package made by the Debian Project.
What is inside a DEB file?
Three members in a fixed order. The first is debian-binary, which says 2.0. The second is control.tar, with a control file, an md5sums list and any scripts. The third is data.tar, with the files and their paths. Both tar archives may be compressed with gzip, xz or zstd, and the data archive may use bzip2 or lzma too.
How do I open a DEB file?
Use dpkg-deb on Linux. Option -c lists files, -x saves them to a folder and -I prints the control data. You can also split the DEB file with ar and open the parts with tar, or use 7-Zip. In our test, dpkg-deb read all 10 good DEB files with content, ar with tar read 9 and 7-Zip read 6.
How do I open a DEB file on Windows?
Install 7-Zip and open the DEB file as an archive. Open the data archive inside it to reach the files. In our test, 7-Zip needed two passes for gzip and xz DEB files and three for bzip2 and lzma ones. It could not open DEB files with zstd inside, so use a Linux system or dpkg-deb for those.
How do I extract a DEB file without installing it?
Type dpkg-deb -x file.deb folder to save the files, and dpkg-deb -e file.deb folder to save the control files. Option -R saves both. If you do not have dpkg-deb, ar x splits the DEB file and tar opens the parts. Nothing is installed by any of these commands.
How do I install a DEB file?
Type sudo apt install ./file.deb. The ./ shows apt that you mean a file, and apt fetches missing dependencies if its lists have them. Or type sudo dpkg -i file.deb when the dependencies are ready. If one is missing, dpkg leaves the package unconfigured and prints dependency problems.
Is it safe to install a DEB file?
Only if you trust the source. Installing a DEB file calls its scripts as root, and a bad script can change anything on the system. In our test, a postinst script printed a line as root. Compare its hash with the one on the download page, and read the scripts first with dpkg-deb -e.
How do I make a DEB file?
Put your files in one folder with the paths they should have, add a DEBIAN folder with a control file and type dpkg-deb --root-owner-group --build folder name.deb. The control file needs a Package, a Version and an Architecture line. In our test, a missing Maintainer or Description gave a warning, and a missing Package, Version or Architecture stopped the build.
How do I check that a DEB file is not damaged?
Save the files and control data with dpkg-deb -x and dpkg-deb -e, then check them with md5sum -c and the md5sums list. This found a flipped byte that dpkg-deb, 7-Zip and dpkg -i all missed. Also compare the hash of the DEB file with the one on the download page. After an install, dpkg -V compares the files on disk with the list dpkg saved.
Why will my DEB file not open?
The usual causes are damaged starts, wrong version text, members in the wrong order, size fields that are too big and text-mode downloads. In our 15 damaged files, 7 needed one small repair and 2 needed none. Five stayed incomplete, and the empty file had nothing to restore. Download the file again in binary mode and compare the hash.
Can I convert a DEB file to RPM?
Yes. The alien program converts packages between formats, and alien --to-rpm made an RPM file from our test DEB file. It left out the scripts until we added --scripts. A converted file is not a native package, because dependencies and library names may differ. We did not install the RPM on a Red Hat system.
What is the difference between .deb and .udeb files?
Wikipedia describes udeb as a stripped-down variant of the DEB format, used by the Debian installer. FileInfo says a udeb has only the essential files and treats it as a separate extension. We built and tested neither udeb nor ipk files, so we cannot compare their bytes with normal DEB files.
Still Stuck With a DEB File? Eight routes out, depending on what went wrong
Start with the damage grid. A zeroed start, a wrong version or a CR LF change explains many cases, and one command fixes it.
Go to the install commands. Use apt install with ./ in front of the name, so dependencies come along.
Is it a program file from inside a package? The guide to ELF program files explains the common Linux program format.
Is it a Windows installer? The MSI installer guide explains the Windows Installer format.
Is it a Mac disk image? The DMG disk image guide explains the Mac format.
Is it a general archive? The ZIP file guide and RAR file guide explain two common archive formats.
Is it a raw copy of a disk? The DD disk image guide and the overview of disk image file types cover those.
Is it a file type you do not know? Browse the file extension resource library, or send it to us on the submit a file type page.