kopia/kopia · error
error writing temporary file
Error message
error writing temporary file
What it means
After successfully creating the temp known-hosts file, writeKnownHostsDataStringToTempFile writes the KnownHostsData string into it with tf.WriteString. If that write fails, the error is wrapped as 'error writing temporary file'. This indicates the local filesystem rejected the write after the file was created.
Solutions
- Free disk space on the filesystem holding the temp directory (usually /tmp or $TMPDIR).
- Check dmesg/system logs for I/O errors on the backing device.
- Set TMPDIR to a different, healthy filesystem and retry.
- Switch to KnownHostsFile (absolute path) instead of KnownHostsData to avoid the temp-file write path.
Example fix
// before (KnownHostsData forces temp-file write)
opt.KnownHostsData = knownHostsLine
// after (write the file yourself once, reference it)
os.WriteFile("/etc/kopia/known_hosts", []byte(knownHostsLine), 0o600)
opt.KnownHostsFile = "/etc/kopia/known_hosts" Defensive patterns
Strategy: validation
Validate before calling
if err := syscallAccess(os.TempDir()); err != nil {
return fmt.Errorf("temp dir not writable: %v", err)
}
df, _ := checkFreeSpace(os.TempDir())
if df < 1<<20 { return errors.New("less than 1MB free in temp dir") } Try / catch
tmp, err := writeKnownHostsDataStringToTempFile(data)
if err != nil && strings.Contains(err.Error(), "error writing temporary file") {
// disk-full / IO error: fall back to KnownHostsFile
return knownhosts.New("/etc/kopia/known_hosts")
} Prevention
- Keep the temp filesystem from filling up; monitor with df alerts.
- Prefer KnownHostsFile to avoid writing known_hosts data to disk at all.
- Investigate I/O errors promptly (dmesg) — writes rarely fail for other reasons.
When it happens
Trigger: Calling getHostKeyCallback with non-empty KnownHostsData when tf.WriteString(data) fails — typically ENOSPC (disk full) on the temp filesystem, an I/O error, or the file being closed/invalidated externally mid-write.
Common situations: tmpfs too small for the write (rare — known_hosts data is small, so usually disk-full or I/O errors); hardware/storage issues in containers; quota enforcement on the temp directory.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- error creating temp file
- can't create tmp file
- can't get random bytes for temporary filename
- can't remove tmp file
- can't write to temp file
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/45147617b3ae0fc7.
Report an issue: GitHub.
Appendix: source
Thrown at repo/blob/sftp/sftp_storage.go:359
o := s.Impl.(*sftpImpl).Options //nolint:forcetypeassert
return fmt.Sprintf("SFTP %v@%v", o.Username, o.Host)
}
func (s *sftpStorage) Close(ctx context.Context) error {
s.Impl.(*sftpImpl).rec.CloseActiveConnection(ctx) //nolint:forcetypeassert
return nil
}
func writeKnownHostsDataStringToTempFile(data string) (string, error) {
tf, err := os.CreateTemp("", "kopia-known-hosts")
if err != nil {
return "", errors.Wrap(err, "error creating temp file")
}
defer tf.Close() //nolint:errcheck
if _, err := tf.WriteString(data); err != nil {
return "", errors.Wrap(err, "error writing temporary file")
}
return tf.Name(), nil
}
// getHostKeyCallback returns a HostKeyCallback that validates the connected host based on KnownHostsFile or KnownHostsData.
func getHostKeyCallback(opt *Options) (ssh.HostKeyCallback, error) {
if opt.KnownHostsData != "" {
// if known hosts data is provided, it takes precedence of KnownHostsFile
// We need to write to temporary file so we can parse, unfortunately knownhosts.New() only accepts
// file names, but known_hosts data is not really sensitive so it can be briefly written to disk.
tmpFile, err := writeKnownHostsDataStringToTempFile(opt.KnownHostsData)
if err != nil {
return nil, err
}
// this file is no longer needed after `knownhosts.New` returns, so we can delete it.
defer os.Remove(tmpFile) //nolint:errcheckView on GitHub (pinned to 82495e54b5)