Double-click a .jar or run a Mono .exe on Linux and something quietly picks the right interpreter for you: update-binfmts is what manages that magic. You will finish with a reliable way to inspect the binary format handlers on a Debian-family system, preview a registration, and check which interpreter would actually be tried for a file. The guide uses update-binfmts from binfmt-support 2.2.2, installed here as package version 2.2.2-7.
Allow about fifteen minutes. You need a shell and access to the machine's binfmt registry. Inspection is normally unprivileged; importing, enabling, disabling, installing or removing a handler usually needs elevated privileges. The examples begin read-only and do not change this machine.
Safety boundary: A bad handler can stop ordinary executables from starting. Never register an ELF interpreter for the ELF magic number. The local manpage warns that this can hang the system before you can run the command again to repair it.
Check the executable and package version first. These are ordinary, read-only commands:
$ command -v update-binfmts
/usr/sbin/update-binfmts
$ update-binfmts --version
binfmt-support 2.2.2
$ dpkg-query -W -f='${Package} ${Version}\n' binfmt-support
binfmt-support 2.2.2-7
The command keeps its persistent descriptions in /var/lib/binfmts. Packaged format files are read from /usr/share/binfmts. You can override those locations with --admindir and --importdir, which is useful when testing a package workflow in a controlled environment.
Checkpoint: If the version or paths differ, keep the installed command's output as your authority. Do not copy output from another host into a change plan.
Display every known format:
$ update-binfmts --display
cli (enabled):
package = mono-runtime
type = magic
offset = 0
magic = MZ
interpreter = /usr/bin/cli
detector = /usr/lib/cli/binfmt-detector-cli
jar (enabled):
package = openjdk-17
type = magic
offset = 0
magic = PK\x03\x04
interpreter = /usr/bin/jexec
detector =
Your list will depend on installed packages. The useful distinction is between the description in the database and the state in parentheses: enabled means the command believes the handler is enabled in the kernel's binfmt_misc interface. An entry can exist while being disabled.
Inspect one entry when you need a focused check:
$ update-binfmts --display jar
jar (enabled):
package = openjdk-17
type = magic
offset = 0
magic = PK\x03\x04
interpreter = /usr/bin/jexec
detector =
Missing or malformed command lines return status 2. A successful display returns status 0, so a script can check $? immediately after the command if it needs to distinguish a missing name from a usable entry.
--find answers a more practical question: which interpreter would be tried for this path? Give it a file that can match a registered format. On this machine a Java archive does:
$ update-binfmts --find /usr/share/java/jrt-fs.jar
/usr/bin/jexec
The result is a list, one interpreter per line. If several handlers match, their order is generally not defined. A userspace detector is tried before a handler without one. Treat multiple lines as a design problem rather than assuming the first result will remain first after a package operation.
If the path does not exist or no handler matches it, do not interpret an empty result as proof that binfmt support is broken. Check the file, then compare its bytes and extension with --display.
--test demonstrates an action without doing it. Use it before any privileged install, especially while checking shell quoting:
$ update-binfmts --test --package demo-handler \
--install demo-handler /usr/bin/printf \
--magic '\x7fDEMO'
install the following binary format description:
package = demo-handler
type = magic
offset = 0
magic = \x7fDEMO
interpreter = /usr/bin/printf
detector =
enable demo-handler with the following format string:
The interpreter and magic value above are deliberately illustrative. Do not install this example as a real handler. The command demonstrates that \x escapes must be protected from the shell with quotes. --magic checks bytes at offset 0 by default; use --offset and, where necessary, --mask only when the format specification requires them. For a filename suffix, use --extension NAME. Extension matching is case-sensitive and the command supplies the leading dot.
Installing is a state-changing, usually privileged operation. It writes the description and attempts to enable the handler in the kernel:
# update-binfmts --install NAME /absolute/path/to/interpreter \
--extension example
Replace every placeholder after reviewing the preview. Keep a record of the exact command and output. Verify with update-binfmts --display NAME and update-binfmts --find /path/to/a/file.example.
Package-managed formats normally use a file in /usr/share/binfmts. It contains one key and value per line:
package demo-handler
interpreter /absolute/path/to/interpreter
magic \xCA\xFE\xBA\xBE
The supported keys correspond to the install specification: package, interpreter, magic, offset, mask, extension, detector, credentials, preserve and fix_binary. Do not mix magic and extension unless you have checked the command's accepted specification for your version.
For a packaged handler, an administrator normally imports the named file with elevated privileges:
# update-binfmts --import demo-handler
# update-binfmts --display demo-handler
Importing without a name processes all format files in the import directory. That is convenient during package configuration, but less focused during manual repair. To undo an imported package format, use its symmetric operation:
# update-binfmts --unimport demo-handler
# update-binfmts --display demo-handler
Do not use --remove as a substitute for --unimport when the entry came from a package. --remove also attempts to disable the handler and removes the database entry, while --unimport follows the package format workflow.
Disabling affects direct execution of matching files and usually needs root:
# update-binfmts --disable NAME
$ update-binfmts --display NAME
NAME (disabled):
Re-enable the same entry with --enable NAME. These actions require binfmt_misc to be compiled into the kernel or loaded as a module. They do not edit the format description. If the status does not change, inspect the command's error and the kernel's binfmt_misc setup instead of repeatedly retrying it.
update-binfmts --display shows the expected entries and enabled or disabled state.--find returns the intended interpreter for a representative file.--test first.--unimport, and a manually installed entry with the matching --remove command.