最終更新
2026年7月、内容を全面的に書き直しました。この記事はもともと2009年に Cygwin 版 rsync の文字コード問題について書いたものですが、その問題はすでに解消されているため、現在この警告で検索して来られる方の悩み(Linux などでの code 24)に合わせて作り直しています。
rsync でバックアップや同期を実行したときに、
file has vanished: "/path/to/source/some-file.tmp" rsync warning: some files vanished before they could be transferred (code 24) at main.c(1356) [sender=3.4.4]
という警告が出て、終了コードが 24 になることがあります。
結論から言うと、これは「rsync がファイル一覧を作った時点では存在したファイルが、実際にコピーする前に消えていた」という警告です。動いているシステムを対象にした同期ではごく普通に起こることで、消えたファイル以外はきちんと転送されています。多くの場合、エラーとして扱う必要はありません。
ただし cron やシェルスクリプトから rsync を呼んでいると、終了コードが 0 以外になるせいで「バックアップ失敗」として通知が飛んできて困る、というのが実際の悩みどころだと思います。この記事では、無視してよいかの判断基準と、cron・スクリプト側での扱い方を中心に説明します。
なぜ起こるのか
rsync は転送対象のファイル一覧を作り、それに沿って中身を転送していきます。ファイルが一覧に載ってから実際にコピーされるまでには時間差があるので、その間に別のプロセスがファイルを削除すると「一覧にはあるのに、いざコピーしようとしたら無い」という状態になります。これが file has vanished です。
ソース側が動いているシステムなら、消える候補はいくらでもあります。
- アプリケーションが作る一時ファイルやロックファイル
- ブラウザなどのキャッシュ
- ログローテーションで削除・リネームされるログ
- メールサーバのスプール(メールファイルはディレクトリ間を頻繁に移動します)
- ビルド中の中間生成物
実際に手元(rsync 3.4.4)で、転送中にソース側のファイルを別プロセスから削除して再現するとこうなります。消えたファイルの分だけ file has vanished: が並び、最後に警告のまとめと終了コード 24 で終わります。
$ rsync -a src/ dst/ file has vanished: "/path/to/src/file300.dat" file has vanished: "/path/to/src/file301.dat" ... rsync warning: some files vanished before they could be transferred (code 24) at main.c(1356) [sender=3.4.4] $ echo $? 24
ポイントは、rsync はこの状況を「エラー(code 23)」とは区別して、専用の終了コード 24 を割り当てていることです。man ページの定義では次のようになっています。
23 - Partial transfer due to error 24 - Partial transfer due to vanished source files
つまり rsync 自身が「これは転送中にソースファイルが消えただけで、他のエラーとは別物」と教えてくれています。この区別のおかげで、スクリプト側で「24 だけは成功扱いにする」という対処が安全にできます。
無視してよいかの判断基準
消えたファイルのパスを見て判断します。
無視してよい典型例は、一時ファイル・キャッシュ・スプール・ログなど「そもそもバックアップする価値のない、消えて当然のファイル」です。この場合バックアップの中身は健全なので、警告は気にしなくて構いません。
逆に、消えるはずのないファイル(業務データや設定ファイルなど)で file has vanished が出るなら、それは rsync ではなくソース側の問題です。誰か(何か)がそのファイルを消しています。心当たりがなければ、削除したプロセスを特定するのが先です。また、NFS などネットワークファイルシステム越しのソースでは、実際には消えていないのにファイルの見え方が不安定でこの警告が出ることがあります。その場合はマウントの安定性を疑ってください。
なお、code 24 ではなく code 23 で終わる場合は原因が別です(パーミッション不足で読めなかった、など)。終了コードごとの意味は rsync の終了コード一覧と意味 にまとめたので、そちらを参照してください。
スクリプト・cron でエラー扱いにしない方法
終了コード 24 だけを成功に読み替えるのが定番です。シェルスクリプトなら次のようにします。
rsync -a /path/to/src/ /path/to/dst/
rc=$?
if [ "$rc" -eq 24 ]; then
rc=0
fi
exit "$rc"
これなら本当のエラー(23 や 11 など)はそのままエラーとして残り、vanished だけを握りつぶせます。set -e を使っているスクリプトでは、rsync ... || rc=$? の形で一度受け止めてから判定してください。
rsync のソースツリーには、これを行う公式のラッパースクリプト support/rsync-no-vanished も同梱されています。終了コードの読み替えに加えて、file has vanished: のメッセージ行そのものを stderr から取り除いてくれるので、cron の「出力があったらメール」という仕組みに引っかからなくなります。中身は短い bash なので、必要な部分だけ自分のスクリプトに取り込むのも手です。
警告自体が出ないようにする方法
出てから握りつぶすのではなく、そもそも出ないようにする方向の対策もあります。
- 消えて当然のファイルを除外する。
sh rsync -a --exclude='*.tmp' --exclude='cache/' /path/to/src/ /path/to/dst/
バックアップ不要なものを除外すれば、警告が減るうえに転送も速くなります。
- ソースを静止させる。確実にやるなら、対象のサービスを止めてから同期するか、LVM・btrfs・ZFS などのスナップショットを作ってスナップショット側から rsync します。ファイルが消えない静止点から読むので、原理的に vanished は起こりません。データベースのように書き込み中のコピーが壊れやすいものは、そもそも rsync ではなく専用のダンプツールを使ってください。
- リトライする。1回目の rsync で大半を転送し、直後にもう1回実行すると差分だけの短い転送になるので、vanished の起こる時間窓が小さくなります。完全にゼロにはなりませんが、実用上はかなり減ります。
歴史ノート:昔この記事は Cygwin の話でした
2009年に書いた初版のこの記事は、まったく別の原因の file has vanished を扱っていました。当時の Cygwin 版 rsync は日本語ファイル名の文字コード変換(Unicode → UTF-8)に失敗することがあり、実際にはファイルが存在するのに opendir failed や file has vanished が出る、という問題です。当時はサードパーティのパッチ版 cygwin1.dll(「UTF-8 Cygwin」)に差し替えるのが解決策でした。
この問題は 2009年12月リリースの Cygwin 1.7 でロケールベースの文字コード処理(UTF-8 がデフォルト)が入って解消し、dll の差し替えは不要になりました。配布サイトもすでに存在しません。
ファイル名の文字コードがらみの rsync トラブルは現在も別の形で残っていて(Mac と Linux の間の濁点・半濁点問題が代表格)、それは rsync でファイル名が文字化けするときの対処 にまとめました。
さいごに
file has vanished(code 24)は「転送中にソースのファイルが消えた」という通知で、動いているシステムの同期では正常の範囲です。消えたファイルのパスを確認して問題なければ、終了コード 24 を成功扱いにするか、公式ラッパー rsync-no-vanished を使ってください。消えるはずのないファイルで出る場合だけ、ソース側を調べる必要があります。
あわせて読みたい: