【GitLab】リストア時に tar: .: Cannot unlink のエラーを踏んだ件と、確実な回避方法

SEAiCのk-yamamoriです。7月ももう終わりですが、皆様はいかがお過ごしでしょうか。
私は社内で利用しているGitLabサーバのリプレース作業をしています。GitLabの正規コマンドでリストア後、データベースは無事に戻ったのに、最後のファイル展開フェーズで謎のエラーが出てリストアが失敗(中断)する事象に遭遇しました。
調べてみると、これはGitLabのバックアップと tar コマンドの仕様が噛み合わずに起きたものでした。
同じエラーで深夜に消耗しているエンジニアが、一瞬で解決できるように原因と対処法を残しておきます。
急いでいる人向け
GitLab 18.5.5〜19.2で tarの仕様変更により発生。 /opt/gitlab/embedded/service/gitlab-rails/gems/gitlab-backup-cli/lib/gitlab/backup/cli/utils/tar.rb内の--unlink-first および --recursive-unlink の指定行を直接削除することで回避可能。GitLabでは19.3で修正予定。
エラー内容
GitLabは公式でバックアップとリストアのツールが用意されています。今回は新旧サーバ間のデータマイグレーションのために使用しました。
"gitlab-backup restore BACKUP=(バックアップファイルのタイムスタンプとバージョン名)"を実行したところ、エラーになり異常終了しました。内容は以下の通りです。
ubuntu@gl:~$ sudo gitlab-backup restore BACKUP=1784693804_2026_07_22_19.0.4-ee (省略) 2026-07-22 07:25:05 UTC -- Deleting backup and restore PID file at [/opt/gitlab/embedded/service/gitlab-rails/tmp/backup_restore.pid] ... done rake aborted! Backup::Error: Restore operation failed: tar: .: Cannot unlink: Invalid argument (Backup::Error) tar: Exiting with failure status due to previous errors /opt/gitlab/embedded/service/gitlab-rails/lib/backup/targets/files.rb:104:in `restore' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/tasks/task.rb:31:in `restore!' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/restore/process.rb:30:in `execute!' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb:101:in `run_restore_task' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb:168:in `block in run_all_restore_tasks' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb:165:in `each_value' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb:165:in `run_all_restore_tasks' /opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb:68:in `restore' /opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rb:22:in `block in restore_backup' /opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rb:83:in `lock_backup' /opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rb:19:in `restore_backup' /opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rake:14:in `block (3 levels) in <main>' /opt/gitlab/embedded/bin/bundle:25:in `<main>' Tasks: TOP => gitlab:backup:restore (See full trace by running task with --trace) Transfering ownership of /var/opt/gitlab/gitlab-rails/shared/registry to registry
調べてみると、GitLabで既にissueとして登録されていました。以下がissueのリンクです。
Restore error: "gtar: .: Cannot unlink: Invalid argument"
発生する環境は以下の通りです。
- GitLabバージョンは18.5.5以降
- RHEL系ディストリビューション(EL9 / EL10):Rocky Linux、RHEL、AlmaLinux などで、パッケージバージョンが
tar-1.34-9.el9_7以降の場合 - Ubuntu 24.04:パッチ適用済みの
tar(例:1.35+dfsg-3ubuntu0.2)を使用している場合(※イシュー内のコメントにて追記・確認された環境)
修正は既にマージ済みで、次バージョンの19.3でリリース見込みとのことです。(2026年7月29日時点の最新バージョンは19.2)
回避策
/opt/gitlab/embedded/service/gitlab-rails/gems/gitlab-backup-cli/lib/gitlab/backup/cli/utils/tar.rb から --unlink-first および --recursive-unlink の指定行を直接削除することで回避できます。
念のため、tar.rbのバックアップを取っておくことをおすすめします。
ubuntu@gl:~$ diff ~/tar.rb.orig /opt/gitlab/embedded/service/gitlab-rails/gems/gitlab-backup-cli/lib/gitlab/backup/cli/utils/tar.rb 65,66d64 < --unlink-first < --recursive-unlink
この状態で再度gitlab-backup restore BACKUP=(バックアップファイルのタイムスタンプとバージョン名)を実行すると成功しました。
リストア時の推奨事項
リストア時の条件はGitLab公式ドキュメントにもまとめられています。詳しくは「復元の前提条件」を参照ください。ここでは、新サーバで実際に実行してみた結果も併せて記載していきます。
復元先のGitLabインスタンスが全く同じバージョンである必要がある
公式Docsでも"バックアップは、作成時とまったく同じバージョンおよびタイプ(CEまたはEE)のGitLabにのみ復元できます。たとえば、CE 15.1.4などです。"と記載されています。GitLabのバージョンは「メジャー.マイナー.パッチ」で表現されます(例:15.1.4であれば15がメジャーバージョン、1がマイナーバージョン、4がパッチバージョン)。リストア時はパッチバージョンまで一致しないとダメなようで、リストア時に以下のエラーが出ました。
現サーバは19.0.4で新サーバが19.0.2だったので、新サーバを19.0.4までアップデートすることで解消しました。
ubuntu@gl:~$ sudo gitlab-backup restore BACKUP=1784693804_2026_07_22_19.0.4-ee Transfering ownership of /var/opt/gitlab/gitlab-rails/shared/registry to git 2026-07-22 06:20:35 UTC -- Unpacking backup ... 2026-07-22 06:25:41 UTC -- Unpacking backup ... done 2026-07-22 06:25:41 UTC -- GitLab version mismatch: Your current GitLab version (19.0.2-ee) differs from the GitLab version in the backup! Please switch to the following version and try again: version: 19.0.4-ee (以下省略)
バックアップのtarファイルが指定されたバックアップディレクトリにあり、オーナーがgitユーザである
これは公式Docsの「LinuxパッケージインストールのGitLabを復元する」にも記載があります。リストア時のコマンドが"gitlab-backup restore BACKUP=(バックアップファイルのタイムスタンプとバージョン名)”なので、ディレクトリとファイルオーナーとファイル名がGitLabから認識できる形式である必要があります。基本的には"gitlab-backup create"で生成されたtarファイルをバックアップディレクトリに配置すれば問題ないですが、エラーになる場合はこれらも確認してみたほうがいいでしょう。
リストア前に、データベースに接続しているプロセスを停止する
こちらも公式で案内されている手順です。
ubuntu@gl:~$ sudo gitlab-ctl stop puma ok: down: puma: 1s, normally up ubuntu@gl:~$ sudo gitlab-ctl stop sidekiq ok: down: sidekiq: 0s, normally up
pumaとsidekiq以外はリストア時に必要なサービスなので、動いていることを確認しておきましょう。
↓ではpumaとsidekiq以外はrunなので大丈夫ですね。
ubuntu@gl:~$ sudo gitlab-ctl status run: alertmanager: (pid 1210) 781631s; run: log: (pid 1204) 781631s run: gitaly: (pid 1193) 781631s; run: log: (pid 1187) 781631s run: gitlab-exporter: (pid 1205) 781631s; run: log: (pid 1194) 781631s run: gitlab-kas: (pid 1208) 781631s; run: log: (pid 1183) 781631s run: gitlab-workhorse: (pid 1202) 781631s; run: log: (pid 1192) 781631s run: logrotate: (pid 825665) 416s; run: log: (pid 1203) 781631s run: nginx: (pid 820734) 3164s; run: log: (pid 1191) 781631s run: node-exporter: (pid 1195) 781631s; run: log: (pid 1186) 781631s run: postgres-exporter: (pid 1197) 781631s; run: log: (pid 1188) 781631s run: postgresql: (pid 1199) 781631s; run: log: (pid 1181) 781631s run: prometheus: (pid 1209) 781631s; run: log: (pid 1198) 781631s down: puma: 17s, normally up; run: log: (pid 1182) 781631s run: redis: (pid 1200) 781631s; run: log: (pid 1185) 781631s run: redis-exporter: (pid 1196) 781631s; run: log: (pid 1180) 781631s run: registry: (pid 820744) 3163s; run: log: (pid 820478) 3208s down: sidekiq: 3s, normally up; run: log: (pid 1184) 781631s
( ゚Д゚)<記事の途中にすまんが、pumaとは、sidekiqとはなんぞや?
( ´∀`)< GitLab architecture overview
リストア後に整合性チェックを行う
リストアが終わると「完遂!完了!」となりがちですが、GitLabでは再設定や整合性チェックを行うコマンドがいくつかあります。リストアが上手くいきシステムが健全な状態であるか確認するために有効です。LinuxパッケージインストールのGitLabを復元するに手順が載っていますので、実行していきます。
ubuntu@gl:/etc/gitlab$ sudo gitlab-ctl reconfigure (省略) Running handlers: [2026-07-23T05:40:36+00:00] INFO: Running report handlers Running handlers complete [2026-07-23T05:40:36+00:00] INFO: Report handlers complete Infra Phase complete, 13/967 resources updated in 15 seconds gitlab Reconfigured!
reconfigureが成功したら、Gitlabを起動します。
ubuntu@gl:/etc/gitlab$ sudo gitlab-ctl restart ok: run: alertmanager: (pid 1159381) 0s ok: run: gitaly: (pid 1159391) 0s ok: run: gitlab-exporter: (pid 1159420) 0s ok: run: gitlab-kas: (pid 1159433) 0s ok: run: gitlab-workhorse: (pid 1159444) 1s ok: run: logrotate: (pid 1159457) 0s ok: run: nginx: (pid 1159463) 0s ok: run: node-exporter: (pid 1159471) 1s ok: run: postgres-exporter: (pid 1159477) 0s ok: run: postgresql: (pid 1159486) 0s ok: run: prometheus: (pid 1159499) 1s ok: run: puma: (pid 1159507) 0s ok: run: redis: (pid 1159515) 0s ok: run: redis-exporter: (pid 1159523) 1s ok: run: registry: (pid 1159532) 0s ok: run: sidekiq: (pid 1159546) 1s
sudo gitlab-rake gitlab:check SANITIZE=true を実行すると、Rakeタスクがリストアが上手くいったかどうかをチェックしてくれます。SANITIZE=trueを使用すると出力からプロジェクト名を伏せてくれます。
※一部手動でマスキングしています。
ubuntu@gl:/etc/gitlab$ sudo gitlab-rake gitlab:check SANITIZE=true Redis version >= 6.2.14? ... yes Ruby version >= 3.0.6 ? ... yes (3.3.11) Git user has default SSH configuration? ... yes Active users: ... 110 Is authorized keys file accessible? ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes Elasticsearch version 7.x-9.x or OpenSearch version 1.x-3.x (9.x recommended for production) ... Exception: User: arn:aws:sts::123456789012:assumed-role/your-ec2-role/i-xxxxxxxxxxxxxxxxxxx is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::987654321098:role/CrossAccount-OpenSearchService All migrations must be finished before doing a major upgrade ... no (You have 100 pending migrations.) For more information see: https://docs.gitlab.com/ee/integration/advanced_search/elasticsearch.html#all-migrations-must-be-finished-before-doing-a-major-upgrade Try fixing it: Wait for all advanced search migrations to complete. To list pending migrations, run `sudo gitlab-rake gitlab:elastic:list_pending_migrations` Checking GitLab App ... Finished Checking GitLab subtasks ... Finished
( ゚Д゚)< またまたすまんが、GitLabにおけるRakeタスクってなんだ?
( ´∀`)< GitLabにおける管理やメンテナンスをしてくれるツールです。詳しくは公式Docsの「Rakeタスク」や「メンテナンスRakeタスク」を見てみてね。
今回は/etc/gitlab/gitlab-secrets.json も一緒に新サーバにお引越ししたので以下の確認コマンドを使用しました。データベース値が復元できるか確認してくれます。
ubuntu@gl:~$ sudo gitlab-rake gitlab:doctor:secrets I, [2026-07-30T04:31:52.700580 #2415673] INFO -- : Checking encrypted values in the database I, [2026-07-30T04:32:26.186402 #2415673] INFO -- : - Import::Offline::Configuration failures: 0 I, [2026-07-30T04:32:26.190591 #2415673] INFO -- : - Observability::GroupO11ySetting failures: 0 I, [2026-07-30T04:32:26.199974 #2415673] INFO -- : - DependencyProxy::GroupSetting failures: 0 I, [2026-07-30T04:32:26.206416 #2415673] INFO -- : - VirtualRegistries::Packages::Npm::Upstream failures: 0 I, [2026-07-30T04:32:26.213854 #2415673] INFO -- : - Ai::Catalog::McpServersUser failures: 0 I, [2026-07-30T04:32:26.242504 #2415673] INFO -- : - Ai::ActiveContext::Connection failures: 0 I, [2026-07-30T04:32:26.246928 #2415673] INFO -- : - SecretsManagement::RecoveryKey failures: 0 I, [2026-07-30T04:32:26.272904 #2415673] INFO -- : - CloudConnector::Keys failures: 0 I, [2026-07-30T04:32:26.279806 #2415673] INFO -- : - VirtualRegistries::Packages::Maven::Upstream failures: 0 I, [2026-07-30T04:32:26.286102 #2415673] INFO -- : - Ai::Catalog::McpServer failures: 0 I, [2026-07-30T04:32:26.495067 #2415673] INFO -- : - WebHook failures: 0 I, [2026-07-30T04:32:29.002605 #2415673] INFO -- : - User failures: 0 (省略) I, [2026-07-30T04:34:08.980454 #2415673] INFO -- : Total: 0 row(s) affected I, [2026-07-30T04:34:08.980481 #2415673] INFO -- : Done!
プロジェクトで添付(アップロード)されたファイルの整合性チェックを行います。ファイル数が多いほどチェック時間がかかります。
ubuntu@gl:/etc/gitlab$ sudo gitlab-rake gitlab:uploads:check Checking integrity of Uploads - 124..633: Failures: 3 - 634..940: Failures: 0 (省略) - 13179..13519: Failures: 0 - 13520..13658: Failures: 0 Done!
続いて、LFS(大容量ファイル)の整合性チェックを行います。
ubuntu@gl:/etc/gitlab$ sudo gitlab-rake gitlab:lfs:check Checking integrity of LFS objects - 1..200: Failures: 0 - 201..400: Failures: 0 - 401..600: Failures: 0 - 601..801: Failures: 0 - 802..1001: Failures: 0 - 1002..1007: Failures: 0 Done!
最後に、アーティファクト(CI/CDパイプラインのジョブ実行時に生成されるファイルやディレクトリなどの成果物)の整合性チェックを行います。今回作業したGitLabサーバではこれがそこそこ多く、全部で20GB近くあったので、整合性チェックにもかなり時間がかかりました。
↓の実行ログを見ていただくと分かりますが、途中にファイルが見つからないエラーが出ていました。確認すると、過去に管理者が手動で不要なファイルを削除していたことが分かりました。こういうことが分かるので実行しておいたほうが良いですね。
このエラーが出てもリストア処理自体は完了しているため、影響範囲を確認した上で次へ進んでOKです。
ubuntu@gl:/etc/gitlab$ sudo gitlab-rake gitlab:artifacts:check Checking integrity of Job artifacts - 1..393: Failures: 0 - 396..602: Failures: 0 - 603..900: Failures: 0 - 903..1296: Failures: 0 - 1297..1616: Failures: 0 - 1617..1980: Failures: 0 - 1981..2304: Failures: 0 - 2305..2644: Failures: 0 - 2645..2948: Failures: 0 - 2949..3170: Failures: 0 (省略) - Job artifact: 63826: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58863/63826/job.log> - Job artifact: 63827: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58864/63827/job.log> - Job artifact: 63830: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58866/63830/job.log> - Job artifact: 63831: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58867/63831/job.log> - Job artifact: 63834: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58869/63834/job.log> - Job artifact: 63835: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58870/63835/job.log> - Job artifact: 63838: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58872/63838/job.log> - Job artifact: 63839: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58873/63839/job.log> - Job artifact: 63840: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58875/63840/job.log> - Job artifact: 63843: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4c/d4/4cd468501fc1a553f49a7098424c51d2ed7f6d546266addcc16e50a008ee148c/2023_03_20/58876/63843/job.log> - Job artifact: 63844: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab- (省略) - 127822..128021: Failures: 0 - 128022..128221: Failures: 0 - 128222..128421: Failures: 0 - 128422..128591: Failures: 0 Done!
最後にデータベースの統計を生成しておきます。
gitlabhq_production=# SET STATEMENT_TIMEOUT=0 ; ANALYZE VERBOSE;
さいごに
リストア時のエラーで困っている人の役に立てば幸いです。
