AdguardTeam/AdGuardHome · error

renaming: %w

Error message

renaming: %w

What it means

On Windows, PendingFile.CloseReplace does an os.Rename of the temp file onto the target path; this error wraps a rename failure. Windows renames fail when the destination exists and is locked by another process, unlike POSIX rename semantics.

Source

Thrown at internal/aghrenameio/renameio_windows.go:43

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.
func newPendingFile(filePath string, mode fs.FileMode) (f PendingFile, err error) {
	// Use the same directory as the file itself, because moves across
	// filesystems can be especially problematic.
	file, err := os.CreateTemp(filepath.Dir(filePath), "")
	if err != nil {

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Close/stop whatever holds the target file open (readers, watchers, editors) before replacing
  2. Remove read-only attributes: attrib -r <file>
  3. Retry with backoff — Windows rename locking is often transient (AV)
  4. Ensure only one instance writes the target
Defensive patterns

Strategy: retry

Try / catch

err := pf.CloseReplace()
if err != nil && strings.Contains(err.Error(), "renaming:") {
    time.Sleep(200 * time.Millisecond)
    err = pf.CloseReplace() // or recreate pending file and retry
}

Prevention

When it happens

Trigger: Calling CloseReplace while the target file is open by another process (config reader, editor, AV); target file has read-only attributes; temp file and target on different volumes; target directory permissions insufficient.

Common situations: Atomic config-file replacement on Windows while the config is being read or watched; read-only files under version control; concurrent AdGuardHome instances writing the same config.

Related errors


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