A Veeam Backup & Replication job completes successfully every night and still reports a warning on one Linux VM: "Unable to perform guest file system indexing…". The backup is fine — the VMDK is captured through the VMware proxy and restores work. What fails is the separate in-guest step that builds the file catalogue, and on SUSE Linux Enterprise 15 the reason is almost always AppArmor, which denies the operation without writing a word to any log you are likely to check.

The first error text sends you somewhere else entirely, so it is worth walking the whole chain in order.

Why file system indexing is a separate thing from the backup

Two different paths run during that job, and confusing them is the reason this warning gets ignored for months:

  • The backup itself goes through the VMware proxy at the hypervisor level. It does not log in to the guest and does not care what is installed inside — the same path that makes reclaiming datastore space a separate job from deleting files in the guest.
  • Guest file system indexing logs in to the guest over SSH, runs updatedb, and brings the resulting database back so you can browse and restore individual files.

So a warning here never means your backup is bad. It means you cannot browse that VM's files in the restore wizard — you can still restore the whole machine or mount the disk manually.

Layer 1: the credential type, and the error that blames the network

The first failure looks like this:

Failed to establish a network connection to the host.

That sentence will cost you an hour if you believe it. Routing was fine, and you can prove it from the Veeam server before touching a firewall:

ssh root@<guest-ip>

If you reach a password prompt, the network is not the problem. "Failed to establish a network connection to the host" is the exact line Veeam shows, and despite the wording it has nothing to do with routing.

In my case the cause was the credential type assigned to the VM. Veeam distinguishes Standard credentials (the Windows style) from Linux (SSH) credentials, and a Linux guest pinned to a Standard credential produces exactly the message above. Assign a Linux credential — root, or an account with elevate to root — in the job's guest processing settings.

The tell that this is the problem: only one Linux VM in the job fails while the others index cleanly. Credentials are per-VM, and the others already had the right type.

Layer 2: is mlocate even installed?

Guest indexing needs updatedb and locate. Check inside the guest:

rpm -q mlocate
which updatedb locate

On a modern SLES build mlocate is usually already there, so this layer is quick to rule out — but rule it out rather than assuming, because the warning text is the same either way.

Layer 3: AppArmor, and why the denial is invisible

With the credential fixed and mlocate present, the job still warns:

Failed to index [/] ... ignoring.

Here is the test that identifies it in one minute. Run both of these in the guest, as root:

# the default invocation - succeeds, exit 0
updatedb

# the same thing, writing somewhere else - fails, as root, with plenty of free space
updatedb -o /tmp/test.db

If the plain command works and -o to any other path fails even as root, that is path confinement, not permissions. No amount of chmod, disk space or sudo will change it, which is exactly why it is so confusing.

SLES ships an enforced AppArmor profile at /etc/apparmor.d/usr.bin.updatedb that permits writing the database only under /var/lib/mlocate/. Veeam calls updatedb -o with its own temporary path under /tmp, and the profile has no rule matching it, so the write is denied.

Confirm which profile is loaded and in what mode:

aa-status | grep -B5 updatedb

The denial is not where you would look for it, which is the single reason this takes so long to find. Where it lands depends on whether auditd is running — and a stock SLES install does not run it:

systemctl status auditd

With auditd active — common on hardened or compliance-audited builds — the denial goes to the audit log and nowhere else:

grep -E 'apparmor=.?DENIED' /var/log/audit/audit.log | grep updatedb | tail -5

Without it, the same denial comes out through the kernel log instead:

journalctl -k | grep -i apparmor
dmesg | grep -i apparmor

Check both before concluding there is no denial to find.

That is the evidence. Everything above it is elimination.

The fix

The quick option puts the profile into complain mode, where it logs what it would have blocked but allows it:

aa-complain /usr/bin/updatedb
aa-status | grep -B5 updatedb    # the "profiles are in complain mode" header above it
                                 # should now cover usr.bin.updatedb

That is enough to make file system indexing succeed, and it is a narrow change — one binary, not AppArmor as a whole.

The tidier option keeps enforcement and adds the path. Find Veeam's current temp path in the audit denial above, add a matching rule to /etc/apparmor.d/usr.bin.updatedb, then re-enforce:

# in the profile, alongside the existing /var/lib/mlocate/ rules
  /tmp/veeam/** rw,

aa-enforce /usr/bin/updatedb

Check that path against your own audit log rather than copying it. Veeam has changed its temporary directory between builds, and a profile with a stale rule is indistinguishable from a profile with no rule — the warning simply comes back after an agent upgrade, long after you have forgotten this was ever configured.

If you choose complain mode, write down that you did. It is the kind of change that silently survives for years and surprises whoever audits the host.

Verify

Run the job — or just the one VM — and check two things:

  1. The session completes with no warning on that VM.
  2. The VM's files are actually browsable in the restore wizard. That is the whole point of file system indexing, and it is the only check that proves the catalogue was really brought back rather than merely attempted.

Then confirm it held over a few nights rather than once. A single clean run after a config change proves less than a week of them.

Related

The other Linux-guest backup trap on this blog is a credential problem too, though a very different one: Error trying to validate NetWorker Server credentials, where the message also points at the network and the real cause is a stale certificate pairing.

Leave a Reply