Inspect and Prepare /etc/machine-id with systemd

Every Linux host keeps a persistent identity in /etc/machine-id, and cloning that value into a golden image breaks every clone at once. You will check the local machine ID, confirm that it has the format systemd expects, and choose the right state for a reusable image. The examples use systemd 255, installed here as package version 255.4-1ubuntu8.17. Allow about fifteen minutes. You need a shell; the inspection steps are unprivileged, while initialising a real system or image normally needs elevated access.

The machine ID is a persistent host identity, not a hostname and not a value to copy casually between machines. Keep it private. If an application needs a stable identifier, derive an application-specific value with a keyed cryptographic hash rather than exposing the machine ID itself.

1. Inspect the installed file

Read the file without changing it:

$ stat -c '%F %s bytes %a %U:%G' /etc/machine-id
$ cat /etc/machine-id

On this system the first command reports a regular file of 33 bytes, and the second prints one line. Do not paste your real value into tickets, screenshots or network diagnostics. The contents should be one newline-terminated string of 32 lowercase hexadecimal characters. That represents 128 bits and must not be all zeroes.

Checkpoint: If the file is missing, empty, contains uppercase letters or has the wrong length, stop before copying the system into an image. A malformed or duplicated identity is an image-build problem, not something to hide with a hostname change.

2. Verify the format without revealing the value

Use a shell check that reports only success or failure. It removes the final newline, checks the length and accepts only lowercase hexadecimal characters:

machine_id=$(tr -d '\n' < /etc/machine-id)
if [ "${#machine_id}" -eq 32 ] && printf '%s' "$machine_id" | grep -Eq '^[0-9a-f]{32}$'; then
    printf '%s\n' 'machine-id format: OK'
else
    printf '%s\n' 'machine-id format: INVALID' >&2
    exit 1
fi

Expected output for a correctly formatted file is:

machine-id format: OK

This checks syntax only. It cannot tell whether the value was accidentally cloned from another host. Treat uniqueness as an image and provisioning responsibility.

3. Understand the two empty-image choices

A generic image that will become several machines must not contain the source host's valid ID. The machine-id manual supports two useful states in the image's /etc directory:

That distinction affects units with ConditionFirstBoot=yes and other first-boot setup. Decide deliberately. A cloud or container image often wants an empty file to avoid first-boot semantics; an installer workflow may want the file absent so first-boot setup runs.

Warning: Do not make this decision by deleting /etc/machine-id on a running host. That changes identity handling for services and can leave a transient mount in use.

4. Prepare a staged image tree

For a directory tree that is not running as the current root, inspect the target before changing it. Replace the placeholder with the staging directory you already use for the image:

$ IMAGE_ROOT='/path/to/staged-root'
$ sudo test -d "$IMAGE_ROOT/etc"
$ sudo ls -l "$IMAGE_ROOT/etc/machine-id"

If you choose the reusable-image, empty-file state, create it with root privileges:

$ sudo install -m 0444 /dev/null "$IMAGE_ROOT/etc/machine-id"
$ sudo stat -c '%F %s bytes %a %U:%G' "$IMAGE_ROOT/etc/machine-id"

Expected output includes a regular file with 0 bytes. This command changes the staged image, not the running host. It overwrites the target if it already exists, so pause first if that image contains a valid identity you may need to preserve.

Recovery: Straightforward before the image is distributed: restore the previous file from your image backup, or remove the empty file if your chosen policy is a missing file. Do not distribute a generic image containing a real host ID.

5. Initialise one machine at install time

For a specific machine, an installer can initialise a missing or empty /etc/machine-id with the installed helper:

$ sudo systemd-machine-id-setup
$ sudo stat -c '%F %s bytes %a %U:%G' /etc/machine-id
$ sudo sh -c 'tr -d "\n" < /etc/machine-id | wc -c'

The helper uses an existing valid D-Bus machine ID when available, otherwise a suitable virtual-machine or container UUID when configured, and otherwise generates a random ID. A successful exit status is 0; the byte-count check should print 32, excluding the newline.

This command is not a reset button. Without --commit, it initialises the file only when it is missing or empty. The --commit mode is for committing a transient ID that systemd placed over the file during early boot, not for casually replacing an established identity. If you need to rotate an existing ID, plan the service impact and backups first, then use the system's documented provisioning procedure.

6. Diagnose first-boot and read-only behaviour

If /etc is read-only during early boot, systemd may bind-mount a temporary file over /etc/machine-id. The real value can be committed later by systemd-machine-id-commit.service when the filesystem becomes writable. A read-only filesystem with no machine-id file at all is an error, so a read-only image should normally contain an empty file.

To see which state is actually on disk, use ordinary read-only checks:

$ findmnt -T /etc/machine-id
$ stat -c '%F %s bytes %a %U:%G' /etc/machine-id

A zero-byte regular file, a valid 32-character file and a bind-mounted temporary file have different meanings. Do not repair a failed boot by writing a random value while services are running. Identify whether the root filesystem, image policy or first-boot workflow is responsible, then recover from the image or provisioning backup.

Done means