AdguardTeam/AdGuardHome · error

closing: %w

Error message

closing: %w

What it means

On Windows, PendingFile.CloseReplace closes the temp file before renaming it over the target; this error means the underlying file.Close() itself failed. On Windows this commonly happens when another process holds the file open (sharing violation).

Source

Thrown at internal/aghrenameio/renameio_windows.go:38

// type check
var _ PendingFile = (*pendingFile)(nil)

// Cleanup implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) Cleanup() (err error) {
	closeErr := f.file.Close()
	err = os.Remove(f.file.Name())

	// Put closeErr into the deferred error because that's where it is usually
	// expected.
	return errors.WithDeferred(err, closeErr)
}

// CloseReplace implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) CloseReplace() (err error) {
	err = f.file.Close()
	if err != nil {
		return fmt.Errorf("closing: %w", err)
	}

	err = os.Rename(f.file.Name(), f.targetPath)
	if err != nil {
		return fmt.Errorf("renaming: %w", err)
	}

	return nil
}

// Write implements the [PendingFile] interface for *pendingFile.
func (f *pendingFile) Write(b []byte) (n int, err error) {
	return f.file.Write(b)
}

// NewPendingFile is a wrapper around [os.CreateTemp].
//
// f.Close must be called to finish the renaming.

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Retry the operation after a short delay — AV locks are usually transient
  2. Add the data directory to antivirus exclusions for the writing process
  3. Ensure only one process performs atomic writes to the same target path

Example fix

// retry pattern
err := pf.CloseReplace()
if err != nil && strings.Contains(err.Error(), "closing:") {
    time.Sleep(100 * time.Millisecond)
    // reopen and rewrite, then CloseReplace again
}
Defensive patterns

Strategy: retry

Try / catch

err := pf.CloseReplace()
if err != nil {
    if strings.Contains(err.Error(), "closing:") {
        time.Sleep(200 * time.Millisecond)
        // rewrite via new PendingFile and retry once
    }
}

Prevention

When it happens

Trigger: Calling CloseReplace on a pending file whose handle can't be closed — an antivirus scanner, indexer, or other process has the temp file open in an incompatible mode; or the file handle was already invalidated.

Common situations: Windows Defender or search indexer briefly locking newly created temp files; a crashed previous run leaving handles; concurrent writers using the same pending-file name pattern.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/b951316c53303a44. Report an issue: GitHub.