kopia/kopia · warning
error unmapping index
Error message
error unmapping index %v (also had close error: %v)
What it means
This error is produced by the closer function returned from mmapFile (unix) when, after the file Close already failed, the subsequent mm.Unmap() also fails. The wrap includes the earlier close error so both failures are visible in one message. It indicates the process could not release the memory mapping — usually because the mapping was already invalidated or memory pressure/OS quirks prevented munmap from succeeding.
Solutions
- Read the embedded '(also had close error: %v)' portion to diagnose the original close failure first
- Ensure the closer is invoked exactly once per openIndex result; add sync.Once if double-close is possible
- Ignore if occurring during process exit — the OS reclaims mappings at exit
- If repeated, check for memory corruption or fs/driver issues on the cache mount
Example fix
// before: calling closer unconditionally on every path, possibly twice
closer(); defer cleanup()
// after: guarantee single invocation
var closeOnce sync.Once
dispose := func() { closeOnce.Do(func() { _ = closer() }) } Defensive patterns
Strategy: try-catch
Try / catch
if err := closer(); err != nil {
if strings.Contains(err.Error(), "unmapping index") {
// likely double-invocation; make disposal idempotent
}
log.Printf("index teardown: %v", err)
} Prevention
- Wrap the closer in sync.Once to guarantee single invocation
- Do not share one openIndex result across goroutines without synchronization
- Rely on the cache API for index lifecycle instead of manual close/unmap
- Inspect the embedded close error in the message before chasing the unmap failure
When it happens
Trigger: Calling the closer returned by openIndex on Unix when both f.Close() (reported via closeErr inside the message) and mm.Unmap() fail — e.g. double-closing the same index, or unmapping after the mapping was already torn down.
Common situations: Bugs where the closer is invoked twice on the same index, or teardown during abnormal shutdown when the process is being torn apart and syscalls start failing.
Related errors
- error unmapping index
- error unmapping index
- error closing index after mmap
- mmap error
- errInvalidBlockSize
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/5b35a7944da01bb4.
Report an issue: GitHub.
Appendix: source
Thrown at repo/content/committed_content_index_disk_cache_unix.go:36
f, err := os.Open(filename) //nolint:gosec
if err != nil {
return nil, nil, errors.Wrap(err, "unable to open file despite retries")
}
mm, err := mmap.Map(f, mmap.RDONLY, 0)
if err != nil {
_ = f.Close()
return nil, nil, errors.Wrap(err, "mmap error")
}
// On Unix, it's safe to close the FD now; the mapping remains valid.
if err := f.Close(); err != nil {
// If close fails, still return mapping, but report error on closer to surface the issue later.
closeErr := errors.Wrapf(err, "error closing index %v after mmap", filename)
return mm, func() error {
if err2 := mm.Unmap(); err2 != nil {
return errors.Wrapf(err2, "error unmapping index %v (also had close error: %v)", filename, closeErr)
}
return closeErr
}, nil
}
return mm, func() error {
if err2 := mm.Unmap(); err2 != nil {
return errors.Wrapf(err2, "error unmapping index %v", filename)
}
return nil
}, nil
}
View on GitHub (pinned to 82495e54b5)