Restore issue with custom BackupPC integration

Hi everyone,

I wanted to share my experience following the suggestions in this thread regarding backing up an NS8 File Server using BackupPC.

Following @stephdl @davidep’s suggestion to run rsync within the Samba module context to preserve UID/GID mappings and ACLs, I implemented a wrapper script solution that successfully solved the backup issue.

Here are the exact steps I followed:

  1. Created a wrapper script on NS8 (/usr/local/bin/rsync-samba-ns8.sh):

    #!/bin/bash
    
    exec runagent -m samba1 podman unshare /usr/bin/rsync "$@"
    
    
  2. Configured BackupPC:

    • Set RsyncClientPath to /usr/local/bin/rsync-samba-ns8.sh

Backup Result: Full and incremental backups now complete successfully without errors, properly fetching data from /home/samba1/.local/share/containers/storage/volumes/.

Issue with Restore: While backups work reliably, I am encountering issues during restores.

The behavior is inconsistent when restoring directories (e.g., shares or homes):

  • Some restore attempts succeed completely.

  • Other attempts (or items within the same restore batch) fail abruptly midway.

Here are the log errors I am receiving in BackupPC:

2026-xx-xx xx:xx:xx restore started below directory /home/samba1/.local/share/containers/storage/volumes/shares to host xxx.xxx.xxx.xxx
2026-xx-xx xx:xx:xx cleaning up after signal PIPE
2026-xx-xx xx:xx:xx restore failed (aborted by signal=PIPE)

and:

2026-xx-xx xx:xx:xx restore started below directory /home/samba1/.local/share/containers/storage/volumes/homes to host xxx.xxx.xxx.xxx
2026-xx-xx xx:xx:xx restore failed (Unable to read 4 bytes)

Could this be related to ACL / extended attribute conflicts, active file locks while the Samba container is running, or subuid/subgid mapping issues when rsync attempts to write back into the namespace via podman unshare?

Has anyone encountered this or found a safe way to handle restores with this setup?

Thanks in advance for your help!

Jamshid

Hi Jamshid,

Good work getting the backup side solid. The restore errors you’re seeing (aborted by signal=PIPE, Unable to read 4 bytes) are rsync’s protocol desync symptoms — they happen when something writes non-protocol bytes onto stdout of the “remote” rsync process, corrupting the binary stream BackupPC is reading. That’s consistent with intermittent failures: it only breaks when the interference happens to occur mid-transfer.

A few things worth checking, in order of likelihood:

  1. Stray stdout output from the wrapper chain. runagent and podman unshare can both print warnings/banners under certain conditions (e.g. namespace setup messages, subuid/subgid range warnings) that go to stdout instead of stderr. Since restore is bidirectional (rsync server writes and reads), any contamination there is far more damaging than on the backup (read-only) path — which would explain why backups are reliable and restores aren’t. Test manually:

    runagent -m samba1 podman unshare /usr/bin/rsync --server ... > /tmp/raw.out 2>/tmp/raw.err
    
    

    and inspect /tmp/raw.out for anything besides pure rsync protocol bytes at the start. Also check whether the samba1 module’s shell profile (.bashrc/.bash_profile//etc/profile.d) echoes anything on non-interactive login — runagent may source it.

  2. ACL/xattr preservation on restore. Backup only reads; restore additionally has to set ACLs/xattrs inside the unshared user namespace, which is a more fragile path under podman unshare’s UID mapping. As a test, try a restore with --no-perms --no-acls --no-xattrs in BackupPC’s restore rsync args (temporarily) and see if the failures disappear — that would confirm it’s an xattr/ACL write failure surfacing as a protocol break rather than a clean rsync error.

  3. Concurrency/timing. If BackupPC runs multiple restore streams in parallel, each spawning its own podman unshare namespace, there can be startup contention. Try a single-threaded restore to rule this out.

  4. Capture more detail with rsync -vvv (or --log-file=/tmp/rsync-restore.log) on the BackupPC side plus journalctl on the NS8 side around the failure timestamp — that’ll show if it’s a killed process (OOM, seccomp denial under the namespace) rather than pure I/O corruption.

My guess is #1 or #2. Let us know what the raw stdout capture shows.

(Drafted with AI assistance.)

Hi Davide,

Thanks for the suggestions.
I performed all the checks to thoroughly rule out environment and system issues. Here is the full report:

  1. Stray STDOUT output from the wrapper chain: I ran the test directly on NS8 inside the agent context:

    runagent -m samba1 podman unshare /usr/bin/rsync --server --numeric-ids . > /tmp/raw.out 2> /tmp/raw.err
    
    
    • Raw STDOUT (hexdump -C /tmp/raw.out): Contains pure binary protocol data (1f 00 00 00). There are zero text banners, namespace warnings, or shell noise at the start of the stream.

    • Raw STDERR (cat /tmp/raw.err): Only recorded the expected SIGINT (code 20) when interrupted with Ctrl+C. No subuid/subgid or podman warnings.

    • Shell profiles: Verified /etc/profile and /etc/bashrc - non-interactive shells correctly redirect script outputs to /dev/null. STDOUT is 100% clean.

  2. ACL / xattr preservation on restore: I tested adding --no-perms --no-acls --no-xattrs to RsyncClientRestoreCmdto rule out permission or attribute issues. It made no difference, the restore still failed with Unable to read 4 bytes. I can confirm ACLs are not the cause of the failure.

  3. Concurrency / Timing / System crashes: I monitored NethServer 8 with journalctl during failed restores. There are no OOM kills, seccomp denials, or podman crashes. The agent environment is totally stable.

  4. Detailed log trace (RestoreLOG): Capturing the detailed transfer log reveals the EXACT BREAKING POINT right after initiating the file reception:

    Remote[2]: recv_files(Bobcat.jpg)
    Remote[1]: invalid uncompressed token length 262144 [receiver]
    Remote[1]: rsync error: protocol incompatibility (code 2) at token.c(295) [receiver=3.2.5]
    Remote[2]: [receiver] _exit_cleanup(code=2, file=token.c, line=295): about to call exit(2)
    Remote[1]: rsync error: protocol incompatibility (code 2) at io.c(1677) [generator=3.2.5]
    Remote[2]: [generator] _exit_cleanup(code=2, file=io.c, line=1677): about to call exit(2)
    Read EOF:
    Tried again: got 0 bytes
    restore failed: Unable to read 4 bytes
    
    

Everything points to a strict protocol/token decompression desync between BackupPC “3” and modern rsync 3.2.5 inside the container during the restore data stream.
For a quick check, I tried adding --no-compress to RsyncRestoreArgs, but the problem is not resolved.
Do you have any recommended clean workarounds to overcome this token limitation?

Thank you again,
Jamshid

The AI agent says this is a protocol version mismatch, not ACL or environment.

BackupPC uses its own rsync protocol implementation (File::RsyncP), old protocol (~28-30). The container runs rsync 3.2.5, newer protocol by default. Token/compression framing differs. That’s the desync.

The AI agent notes --no-compress doesn’t fix it — problem is protocol version, not compression.

Suggested fix: force old protocol. Add --protocol=28 to rsync args, both backup and restore side (RsyncArgs, RsyncRestoreArgs, wrapper script if needed).

If 28 fails, the AI agent suggests trying 29 or 30.

Backup worked without it — restore may be more sensitive to this. The AI agent recommends setting it on both sides.

I hope it helps.

(Drafted with AI assistance.)

Hi Davide,

I really appreciate your collaboration and all your suggestions.
I tested the steps you mentioned regarding the protocol versions, but unfortunately, I still couldn’t get the restore process to work on BackupPC3.

Because of this and following up on what we discussed in my previous thread (How to back up an NS8 file server with BackupPC), I decided to go ahead and test BackupPC 4 on NS8.
Now I have to confirm that this solved the issue, both backup and restore jobs are now working perfectly.

Thanks again for all your time and support,
Jamshid

did you use my module and did you succeed with it to restor and backup e a nethserver 8