Skip to content

GC: Repository corruption due to premature deletion of orphaned file #246

@syntonyze

Description

@syntonyze

Version

7.6.0-SNAPSHOT

Operating System

Linux/Unix

Bug description

Run some traffic to a git repository (via Gerrit) and perform cyclic GCs via:

jgit --git-dir $REPO_PATH gc --preserve-oldpacks --no-pack-refs

Occasionally, the GC fails with MissingObjectException (See logs provided).
When analysing the problem, we notice that the previous run removed an "orphaned file" (possibly containing the missing object).

2026-02-26 04:29:45 +0100 [main] WARN org.eclipse.jgit.internal.storage.file.GC - Deleted orphaned file /path/repo.git/objects/pack/pack-c97999fd8c6889f32716a19cd50600b84b961606.idx

The associated packfile, however it can still be found on disk, and its creation time is the same time as the deleted orphaned file.

root@repo /path/repo.git/objects/pack # stat pack-c97999fd8c6889f32716a19cd50600b84b961606.pack
  File: pack-c97999fd8c6889f32716a19cd50600b84b961606.pack
  Size: 3445      	Blocks: 8          IO Block: 4096   regular file
Device: 10304h/66308d	Inode: 36226711    Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2026-02-26 04:29:45.925940419 +0100
Modify: 2026-02-26 04:29:45.901940626 +0100
Change: 2026-02-26 04:29:45.905940592 +0100
 Birth: 2026-02-26 04:29:45.901940626 +0100

Actual behavior

An IDX file is deleted because the related pack is not found on disk.

2026-02-26 04:29:45 +0100 [main] WARN org.eclipse.jgit.internal.storage.file.GC - Deleted orphaned file /path/repo.git/objects/pack/pack-c97999fd8c6889f32716a19cd50600b84b961606.idx

Expected behavior

Whilst I am not sure why the pack file cannot be found on disk (FS resolution, creation order?), I guess there would be a few things Jgit could do to make this logic more robust:

  • At the very least it could re-try.
  • Also, the idx file should not necessarily be removed, but moved to preserved and restored if necessary.
  • Honour the prunePackExpire before removing it.

Relevant log output

Running: java_args='-Xss8m -Xms16g -Xmx16g' time /usr/local/bin/jgit-7.6.0-vanilla.sh --git-dir /path/repo.git gc --preserve-oldpacks --no-pack-refs
Counting objects:       220502
Finding sources:        100% (220502/220502)
Getting sizes:          100% (66371/66371)
Compressing objects:    100% (16269/16270)
Writing objects:        100% (220502/220502)
Selecting commits:      100% (45727/45727)
Building bitmaps:       100% (2410/2410)
org.eclipse.jgit.api.errors.JGitInternalException: Garbage collection failed.
        at org.eclipse.jgit.api.GarbageCollectCommand.call(GarbageCollectCommand.java:254)
        at org.eclipse.jgit.pgm.Gc.run(Gc.java:66)
        at org.eclipse.jgit.pgm.TextBuiltin.execute(TextBuiltin.java:239)
        at org.eclipse.jgit.pgm.Main.execute(Main.java:247)
        at org.eclipse.jgit.pgm.Main.run(Main.java:135)
        at org.eclipse.jgit.pgm.Main.main(Main.java:106)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:106)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)
Caused by: org.eclipse.jgit.errors.MissingObjectException: Missing unknown c43c0d58a8de747eb2d48d9c491f01960c9824ba
        at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:149)
        at org.eclipse.jgit.lib.ObjectReader$1.open(ObjectReader.java:295)
        at org.eclipse.jgit.revwalk.RevWalk$2.next(RevWalk.java:1311)
        at org.eclipse.jgit.internal.storage.pack.PackWriter.findObjectsToPack(PackWriter.java:2070)
        at org.eclipse.jgit.internal.storage.pack.PackWriter.preparePack(PackWriter.java:1021)
        at org.eclipse.jgit.internal.storage.pack.PackWriter.preparePack(PackWriter.java:937)
        at org.eclipse.jgit.internal.storage.file.GC.writePack(GC.java:1336)
        at org.eclipse.jgit.internal.storage.file.GC.repack(GC.java:911)
        at org.eclipse.jgit.internal.storage.file.GC.doGc(GC.java:320)
        at org.eclipse.jgit.internal.storage.file.GC.gc(GC.java:250)
        at org.eclipse.jgit.api.GarbageCollectCommand.call(GarbageCollectCommand.java:236)
        ... 10 more
Command exited with non-zero status 1

Other information

Repo config:

[core]
	repositoryformatversion = 0
	filemode = true
	bare = true
	logallrefupdates = false
[gc]
	pruneExpire = 360.minutes.ago
	prunePackExpire = 120.minutes.ago
	auto = 0
	autoPacklimit = 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions