opentofu/opentofu · error
failed to replace %s with temporary file %s: %w
Error message
failed to replace %s with temporary file %s: %w
What it means
The final atomicity step renames the temp file over credentials.tfrc.json via replacefile.AtomicRename. Failure means the platform refused the rename: on Windows, the target is open by another process (editor, antivirus, sync agent); on POSIX, cross-device rename, missing target permissions, or filesystem errors. The temp file is cleaned up by the deferred remove and the original file is unchanged.
Source
Thrown at internal/command/cliconfig/credentials.go:429
if !moved {
os.Remove(name)
}
}(f, tmpName)
// Write the credentials to the temporary file, then immediately close
// it, whether or not the write succeeds.
_, err = f.Write(newSrc)
f.Close()
if err != nil {
return fmt.Errorf("cannot write to temporary file %s: %w", tmpName, err)
}
// Temporary file now replaces the original file, as atomically as
// possible. (At the very least, we should not end up with a file
// containing only a partial JSON object.)
err = replacefile.AtomicRename(tmpName, filename)
if err != nil {
return fmt.Errorf("failed to replace %s with temporary file %s: %w", filename, tmpName, err)
}
// Credentials file should be readable only by its owner. (This may
// not be effective on all platforms, but should at least work on
// Unix-like targets and should be harmless elsewhere.)
if err := os.Chmod(filename, 0600); err != nil {
return fmt.Errorf("cannot set mode for credentials file %s: %w", filename, err)
}
moved = true
}
if new != nil {
s.configured[host] = new.ToStore()
} else {
delete(s.configured, host)
}
View on GitHub (pinned to 3561785c48)
Solutions
- Close editors/sync tools that may hold the credentials file open, then retry tofu login
- On Windows, exclude the tofu config dir from on-access AV scanning, or retry after a short delay (scans are transient)
- Ensure the config dir and its temp files live on the same filesystem/mount
Defensive patterns
Strategy: retry
Try / catch
err := src.StoreForHost(ctx, host, creds)
if err != nil && strings.Contains(err.Error(), "failed to replace") {
// Windows: target usually held open by AV/editor; close and retry
for attempt := 0; attempt < 3; attempt++ {
time.Sleep(500 * time.Millisecond)
if err = src.StoreForHost(ctx, host, creds); err == nil {
break
}
}
} Prevention
- Close editors and pause sync clients (OneDrive/Dropbox) before tofu login/logout on Windows
- Exclude the tofu config dir from on-access antivirus scans on managed endpoints
- Keep the config dir off NFS where rename semantics are unreliable
When it happens
Trigger: An editor or file-sync tool (OneDrive/Dropbox) holding credentials.tfrc.json open on Windows; antivirus scanning the freshly renamed file; the config dir and temp file ending up on different mounts; NFS rename semantics failing.
Common situations: tofu login while the credentials file is open in VS Code; sync clients watching the home dir; heavily AV-instrumented corporate Windows machines.
Related errors
- cannot read %s: %w
- cannot create temporary file to update credentials: %w
- cannot write to temporary file %s: %w
- cannot set mode for credentials file %s: %w
- failed to read symlink %q: %w
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/f1692687833be1d4.
Report an issue: GitHub.