SUBMIT A FILE TYPE CONTACT US SUPPORT ABOUT US

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.

35 min read Updated October 2026 Checked against Debian manuals and tests

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

Quick facts about the DEB file extension
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/vnd.debian.binary-package. 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.

Read the start of DEB files with Python
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")
The answer for g03-xz.deb from our test
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.

The answer for a package with one flipped byte in data.tar.xz
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
First bytes of the kinds of files you may find
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.

A decision chart: read the first eight bytes of the DEB file. If they spell !⁠<arch> and a line feed, and the first member is debian-binary, it is a modern DEB file. If they spell 0.939000, it is an old DEB file that only dpkg-deb reads. If they are ed ab ee db, it is an RPM file. If they are 1f 8b, it is a gzip file. If they are zeros or something else, the start is wiped or the file is another format
First bytes and member names name the kind. The ending only says DEB.

Three more clues about your DEB file

The file command Version 5.45 named every modern package in our test and printed its compression, like control.tar.zst. For the old format and for a wiped start, it said only data.
The ar t command It printed the three member names of all 10 modern DEB files. For the old format it said file format not recognized.
The dpkg-deb -I command It printed the control data of all 11 good DEB files, the old format too. It stops with an error on damaged starts.
The ending DEB files end in .deb. Installer images use .udeb. Read the bytes before you trust any ending.

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.

The layout of one DEB file drawn to scale. The file has 201,504 bytes. The first 8 bytes are the magic. A 60-byte header and 4 bytes of debian-binary come next, then a 60-byte header and 486 bytes of control.tar.gz, then a 60-byte header and 200,826 bytes of data.tar.gz. The control archive stores three files: conffiles, control and md5sums. The data archive stores 16 entries, including 4 files
Our 201,504-byte package, drawn to scale. The data archive is almost all of the file.
The parts of DEB files and where they start
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.

Files in the control archive
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 of the data archive and our tests
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.

26 DEB files tested
11 good DEB files we built
15 damaged DEB files
4 readers used

The 11 good DEB files we built

The 11 good DEB files and what they test
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.

Which readers opened the 10 good DEB files that have files
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.
A grid of four readers against seven kinds of good DEB file. dpkg-deb returned all 4 test files from every kind. The installer dpkg -i did the same. ar with tar returned them from every kind except the old format. 7-Zip returned them from gzip and xz packages and from uncompressed packages after two passes, and from bzip2 and lzma packages after three passes. It could not open zstd packages, and it gave back only the control part of the old format
dpkg-deb and dpkg -i read all 7 kinds. ar with tar read 6. 7-Zip read 4.

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.

Damaged DEB files that gave back all 4 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.

The first bytes show most wrapper damage Our script flagged 12 of the 15 damaged files. It found no problem in the 11 good ones.
Only a hash finds a flipped byte inside a tar Four readers returned the file with the flipped byte and raised no error. The md5sums check found it.
Cut files still give most of their files Three of the four test files came back complete from four cut or damaged copies. photo.bin came back in part, from 90,624 to 188,928 bytes of 200,000.
Wrapper fixes took one command Putting back the magic, version text, member order, size field or line feeds gave a DEB file that dpkg accepted.

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.

Neeraj Singh

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.”

Neeraj Singh Manager, Tech Support & Operations 19+ years fixing Windows and system errors

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.

Which programs open DEB files
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.

Five dpkg-deb commands that install nothing
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
What dpkg-deb -I printed for our gzip package (shortened)
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.

Split a DEB file with ar and open the parts with tar
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.

Open a gzip or xz package with 7-Zip in two 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.

deb(5) manual page

Format rules, from the dpkg authors

Debian manual

dpkg-deb manual page

Every option for listing, extracting and building

Debian manual

DEB on Wikipedia

History, variants and tools

Wikipedia page

FileInfo entry for .deb

Programs listed by system

FileInfo page

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.

  1. Check the DEB file first with dpkg-deb -I. Read its name, version, architecture and Depends line.
  2. Install it with sudo apt install ./file.deb. The ./ matters, because without it apt looks for a package of that name in its lists.
  3. Or use sudo dpkg -i file.deb when you have the dependencies ready. If one is missing, dpkg stops and leaves the package unconfigured.
  4. List what it added with dpkg -L, and remove it with dpkg -r or dpkg -P.
Check, install, list and remove a DEB file
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
What we saw when we installed
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.

What dpkg -i printed (shortened)
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.

What apt planned (shortened)
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.

  1. Make a folder named for the package, and copy your files into it with the paths they should have on the target system.
  2. Add a DEBIAN folder with a control file. Add md5sums, conffiles and scripts if you need them.
  3. Build with dpkg-deb --root-owner-group --build, the folder name and the new file name.
  4. Check the result with dpkg-deb -I and -c, then test an install on a machine you can reset.
A control file that builds without warnings
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.
Make a DEB file from a folder
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.

One folder built with every choice
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.

Build an old format DEB file
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.

  1. Save the control files with dpkg-deb -e and the data files with dpkg-deb -x.
  2. Go into the data folder and check the files with md5sum -c.
  3. After you install, use dpkg -V to compare the installed files with the list dpkg saved.
  4. Hash the DEB file itself with sha256sum and compare it with the number on the download page.
Check the files in a DEB file
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
The answer for the package with one flipped byte
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
What the checks found
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.

A grid of 15 damage tests with columns for files back before and after repair, installs before and after, and the fix. A zeroed start, a text-mode transfer and a 3.0 version gave no installs at first and were fixed by writing the bytes back. A wrong member order and a too-big size field were fixed by packing in order and setting the size. A damaged control archive and a missing Package line were fixed by writing the control file again. Versions 2.5 and an extra member needed no fix. A cut file, a zeroed second half and an xz flip gave 3 of 4 files. A missing tail was read by 7-Zip. An empty file gave nothing. A flipped byte inside an uncompressed package installed with one wrong file
15 tests. Files back: green is all 4, amber is some and red is none. Installs: yes, no or wrong.
Damage we fixed and how
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.

Four repairs we tested, on copies of the DEB files
# 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.

Fix a size field that is too big
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.

Two control file repairs we tested
# 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

A missing tail can still be read The copy that lost its last 100 bytes stopped dpkg-deb and ar. 7-Zip still read all 4 files from it. The lost bytes were at the end of the xz stream, and the data was intact.
Cut copies and zeroed halves Option -x of dpkg-deb saved the 3 small files intact and part of photo.bin. It gave 99,328 bytes from the copy cut in half and 90,624 bytes from the copy with a zeroed second half. The rest was gone.
A flipped byte in compressed data The xz copy stopped at the flip and returned 188,928 bytes of photo.bin. The checksum inside xz did its job, and bytes after the flip were lost.
A flipped byte in an uncompressed package It installed, and no reader raised an error. The md5sums check found photo.bin. The fix is a fresh copy of the file.
An empty file dpkg-deb said "unexpected end of file in archive magic version number". There are no bytes to restore, so download the file again.

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.

What the conversion routes made
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.
Convert a DEB file and check the result
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.

Package kinds and how to spot them
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.

Software packages The common meaning. Ar archives with a version file, control archive and data archive.
Installer packages The udeb variant, from Wikipedia and FileInfo. Not tested.
Other package types RPM files do the same job elsewhere. alien converts between the two.
Not always a package Read the first bytes before you trust the ending.

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.

Facts about DEB files
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/vnd.debian.binary-package. The names x-debian-package and x-deb are deprecated.
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

Your DEB file will not open

Start with the damage grid. A zeroed start, a wrong version or a CR LF change explains many cases, and one command fixes it.

You want the program on your system

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.