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

  1. Free disk space on the filesystem holding the temp directory (usually /tmp or $TMPDIR).
  2. Check dmesg/system logs for I/O errors on the backing device.
  3. Set TMPDIR to a different, healthy filesystem and retry.
  4. 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

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


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:errcheck

View on GitHub (pinned to 82495e54b5)