layout: ../../../layouts/BlogLayout.astro title: “Der NFSv4-Timestamp-Bug: Warum deine Dateidaten die Migration nicht überleben” description: “NFSv4 überschreibt stillschweigend Datei-Timestamps während der Write-Back-Verarbeitung — betrifft rsync, cp -p und jedes Migrationstool. Hier erfährst du, was passiert und was du tun kannst.” date: “2026-03-02” author: “syncopio Team” category: “Best Practices” readingTime: “8 min” slug: “nfsv4-timestamp-bug” tags: [“nfs”, “nfsv4”, “timestamps”, “migration”, “linux”, “bug”] locale: “de”

Du kopierst 500 Dateien auf ein NFS-Share. Die Größen stimmen. Die Hashes stimmen. Dein Tool sagt, die Zeitstempel wurden erhalten. Du gehst weiter.

Nur dass die Zeitstempel falsch sind. Jeder einzelne. Und nichts hat dich gewarnt.

Wir haben das bei einem routinemäßigen Migrationstest entdeckt. Das client-seitige stat zeigte die korrekten Daten, die wir sorgfältig von der Quelle übernommen hatten. Aber als wir dieselben Dateien direkt auf dem NFS-Server geprüft haben, war jede Änderungszeit stillschweigend durch den Zeitpunkt des Transfers ersetzt worden.

Das ist kein Bug in rsync. Es ist kein Bug in cp, tar oder irgendeinem anderen Tool. Es ist fest eingebaut in die Art, wie NFSv4 Dateischreibvorgänge handhabt. Jedes Kopiertool der Welt liefert dasselbe Ergebnis, wenn es auf ein NFSv4-Ziel schreibt.

Wer ist betroffen?

Jeder, der Dateien auf ein NFSv4-Share kopiert, wo die originalen Dateidaten wichtig sind: Backups, Migrationen, Compliance-Archive, inkrementelle Syncs. Wenn dein Ziel-Mount NFSv4 verwendet, sind deine Zeitstempel möglicherweise bereits falsch.

Gib deine E-Mail-Adresse ein, um den Fix und die vollständige technische Analyse zu lesen

Kein Spam. Jederzeit abbestellbar.

Der Einzeiler-Fix

Stelle deinen Ziel-Mount auf NFSv3 um:

mount -t nfs -o vers=3,rw,hard,noatime 192.168.1.100:/export /mnt/dest

Das war’s. NFSv3 hat den Mechanismus nicht, der das verursacht. Problem gelöst.

Wenn du rsync verwendest, mounte einfach das Ziel mit vers=3 neu. Wenn du syncopio nutzt, musst du gar nichts tun. Es erkennt NFSv4-Ziele automatisch und wechselt zu NFSv3, wenn Timestamp-Erhaltung aktiviert ist. Keine Konfiguration nötig.

syncopio advantage

syncopio handhabt das automatisch. Wenn Timestamp-Erhaltung aktiviert ist und das Ziel NFS ist, erzwingt es NFSv3 für den Ziel-Mount. Quell-Mounts bleiben auf NFSv4. Du musst nichts anfassen.

So prüfst du, ob du betroffen bist

1. Welche NFS-Version nutzt dein Ziel?

mount | grep nfs

Wenn du vers=4 oder nfs4 auf dem Ziel siehst, lies weiter.

2. Sind deine Zeitstempel tatsächlich korrekt?

Prüfe nicht vom Client aus. Der Client lügt. Er cached den alten Wert und zeigt dir, was du erwartest.

Prüfe direkt vom Server aus, oder mounte mit noac neu, um den Cache zu umgehen:

mount -o remount,noac /mnt/nfs-dest
stat /mnt/nfs-dest/somefile.txt

Wenn die Änderungszeit den Zeitpunkt deiner letzten Kopie zeigt statt das Originaldatum, hat es dich erwischt.


Das ist alles, was du zum Beheben brauchst. Der Rest dieses Posts ist das Rabbit Hole: wie wir es gefunden haben, warum es passiert und warum auch Linux 6.17 nicht hilft.


Wie wir es gefunden haben

Wir haben eine NFS-zu-NFS-Migration getestet: 505 Dateien in 26 Verzeichnissen mit aktivierter Timestamp-Erhaltung. Transfer abgeschlossen. Checksummen stimmten. Client-seitiges stat zeigte korrekte Zeitstempel. Alles grün.

Dann haben wir den NFS-Server geprüft. Jede Datei hatte das falsche Datum. Die Änderungszeiten, die wir gesetzt hatten, waren weg, ersetzt durch den exakten Zeitpunkt des Transfers.

Unser erster Gedanke: Wir machen etwas falsch. Vielleicht flushen wir Schreibvorgänge nicht korrekt, bevor wir den Zeitstempel setzen. Wir haben dort einen echten Fehler behoben (falscher File-Descriptor beim Sync), aber das hat das Timestamp-Problem nicht gelöst.

Also haben wir andere Tools probiert:

rsync -a source.txt /mnt/nfs-dest/
cp -p source.txt /mnt/nfs-dest/
touch -r source.txt /mnt/nfs-dest/source.txt

Gleiches Ergebnis. Jedes Tool. Korrekte Zeitstempel auf dem Client, falsche Zeitstempel auf dem Server.

Das schloss unseren Code aus. Das war Protokoll-Ebene.

Warum es passiert

NFSv4 führte ein Feature namens Delegations ein. Wenn du eine Datei zum Schreiben öffnest, kann der Server deinem Client exklusive Kontrolle übergeben. “Hier, kümmere dich drum, gib es einfach zurück, wenn du fertig bist.” Der Client puffert Schreibvorgänge lokal, statt sie sofort an den Server zu senden. Das ist großartig für die Performance.

Hier geht es schief:

  1. Du schreibst Daten in die Datei, die im Client-Speicher bleiben
  2. Du schließt die Datei, und der Client beginnt, die Delegation zurückzugeben
  3. Du setzt den Zeitstempel auf die originale Quellzeit. Der Client sendet SETATTR an den Server, der das korrekte Datum setzt
  4. Der Server verarbeitet das Schließen und flusht die gepufferten Schreibvorgänge
  5. Diese Schreiboperationen aktualisieren die Änderungszeit auf jetzt

Schritt 5 macht Schritt 3 rückgängig. Der Server hat den Zeitstempel gesetzt, den du angefordert hast, und ihn dann sofort überschrieben, weil die verzögerten Schreibvorgänge nach deiner Zeitstempeländerung ankamen.

Das ist kein Tool-Bug

rsync, cp, tar, Go, Python, Shell touch: sie alle laufen gegen dieselbe Wand. Das NFSv4-Protokoll selbst überschreibt deinen Zeitstempel als Nebeneffekt der verzögerten Schreibverarbeitung. Kein noch so guter Anwendungscode kann das verhindern.

Warum du es nicht merkst

Das ist der schlimmste Teil. NFS-Clients cachen Dateiattribute aggressiv. Wenn dein Tool einen Zeitstempel setzt, aktualisiert der Client seinen lokalen Cache mit dem Wert, den er gerade gesendet hat. Jeder nachfolgende stat-Aufruf liest aus dem Cache, nicht vom Server. Also besteht deine Verifizierung. Dein Tool meldet Erfolg. Alles sieht gut aus.

Der Server hat den Zeitstempel bereits überschrieben, aber der Client erfährt es erst, wenn der Cache abläuft — typischerweise 30 bis 60 Sekunden später. Bis dahin hat dein Tool längst die nächste Datei verarbeitet.

Dein Verifizierungsschritt besteht, obwohl die Daten falsch sind.

Warum Verzeichnisse überleben

Verzeichnisse haben keine ausstehenden Schreibvorgänge. Keine gepufferten Daten bedeuten keinen verzögerten Flush, der kein Timestamp-Überschreiben auslöst. Deshalb kommen Verzeichnisdaten korrekt durch, während Dateidaten es nicht tun — und warum du das möglicherweise komplett übersiehst, wenn du nur stichprobenartig Ordner prüfst.

Warum NFSv3 funktioniert

NFSv3 hat keine Delegations. Schreibvorgänge gehen direkt an den Server. Wenn du nach dem Schließen einer Datei einen Zeitstempel setzt, gibt es kein verzögertes Write-Back, das darum wetteifert, ihn zu überschreiben. Was du setzt, ist das, was du bekommst.

Wir haben dieselbe Test-Suite mit 505 Dateien über NFSv3 ausgeführt:

Null Fehler. Dieselben Dateien, derselbe Code, derselbe Server. Der einzige Unterschied war die Protokollversion.

”Einfach den Kernel updaten”

Man würde denken, ein Kernel-Update würde das beheben. Es gibt eine relevante Patchserie. Jeff Layton hat im Juli 2025 eine 8-Patch-Serie eingereicht, die sich mit der Handhabung delegierter Zeitstempel im NFS-Server-Daemon befasst:

nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation

Aber hier ist der Haken: Dieser Fix zielt auf NFSv4.2+ Attribut-Delegations ab, ein neueres Feature, bei dem der Server die Zeitstempel-Verwaltung explizit an den Client übergibt. Das ist ein anderer Mechanismus als die regulären Write-Delegations, die unser Problem verursachen.

Wir haben auf Linux 6.17 (Proxmox PVE Kernel) getestet, mit Client und Server auf demselben Host. Der Bug besteht weiter.

Kein Kernel behebt das

Das Timestamp-Überschreiben passiert bei regulären NFSv4-Write-Delegations, die seit der Einführung von NFSv4 der Standard sind. Der Kernel-Patch behebt die neueren NFSv4.2 Attribut-Delegations, was eine ganz andere Sache ist. Für reguläre Write-Delegations ist das Aktualisieren der mtime beim Schreiben das beabsichtigte Protokollverhalten. Es ist kein Bug. Keine Kernel-Version ändert das.

Das wird nicht verschwinden. Jeder jemals ausgelieferte Kernel hat dieses Verhalten, und jeder zukünftige auch, weil es so designt wurde. NFSv3 ist kein temporärer Workaround. Es ist die richtige Wahl für Schreibziele, wo Zeitstempel wichtig sind.

Was du tun solltest

  1. Ziel-Mounts: Verwende NFSv3. Füge vers=3 zu deinen Mount-Optionen hinzu. Das ist der Fix. Er ist zuverlässig, einfach und funktioniert auf jedem Kernel.
  2. Quell-Mounts: NFSv4 ist in Ordnung. Der Bug betrifft nur Schreibvorgänge. Lesen von NFSv4 funktioniert einwandfrei.
  3. Vertraue nicht dem client-seitigen stat. Wenn du Zeitstempel verifizieren musst, prüfe direkt auf dem Server oder mounte mit noac.
  4. NFSv4 ist immer noch großartig für Leseoperationen. Kerberos-Unterstützung, Single-Port-Firewall-Regeln, Delegation-Performance für leselastige Workloads. Verwende es einfach nicht für Schreibziele in metadaten-sensitiven Workflows.

Weiterführende Lektüre:

Referenzen: