hashicorp/terraform · error
failed to create temp known_hosts file
Error message
failed to create temp known_hosts file: %s
What it means
This error occurs inside buildSSHClientConfig when Terraform's SSH provisioner tries to create a temporary file to hold the user-supplied host_key for known_hosts verification. The knownhosts package only accepts file paths, so Terraform writes the in-memory host key to a temp file via ioutil.TempFile. If the OS cannot create that temp file (permissions, disk full, exhausted inodes, invalid TMPDIR), the entire SSH connection setup aborts.
Solutions
- Verify the system temp directory is writable: run `echo $TMPDIR` (or check /tmp) and confirm the Terraform process user can create files there.
- Free disk space or increase the temp directory quota if the volume is full.
- If running in a container, mount /tmp as a writable tmpfs or volume with adequate size.
- Check open file descriptor limits (ulimit -n) and raise them if EMFILE is the underlying cause.
- If the environment temp dir is restricted, set TMPDIR to a writable location before invoking Terraform.
Example fix
# before (TMPDIR points to read-only path) export TMPDIR=/readonly/tmp terraform apply # after export TMPDIR=/var/tmp/tf-work mkdir -p $TMPDIR terraform apply
Defensive patterns
Strategy: validation
Validate before calling
// Before configuring the SSH connection, verify temp dir writability
import (
"os"
"path/filepath"
)
func checkTempDirWritable() error {
f, err := os.CreateTemp("", "tf-precheck")
if err != nil {
return fmt.Errorf("temp directory not writable: %w", err)
}
f.Close()
os.Remove(f.Name())
return nil
}
// Call before provisioning:
// if err := checkTempDirWritable(); err != nil { log.Fatal(err) } Prevention
- In CI containers, ensure /tmp is a writable tmpfs or volume with adequate free space.
- Set TMPDIR explicitly to a known-writable path in your Terraform runner environment.
- Monitor disk space on the runner to prevent ENOSPC during provisioning.
- Raise ulimit -n if running many concurrent SSH connections.
When it happens
Trigger: Calling an SSH communicator with a non-empty host_key connection parameter, where ioutil.TempFile("", "tf-known_host") fails. Triggered by: read-only or missing system temp directory, ENOSPC (disk full), EMFILE (too many open files), or a TMPDIR environment variable pointing to a non-existent or unwritable path.
Common situations: Running Terraform in a hardened container or CI runner where /tmp is mounted read-only or has a noexec constraint with tight space limits. Setting TMPDIR to a path that doesn't exist. Running under a service account without write access to the default temp directory. Disk exhaustion on the worker node during a large provisioning run.
Related errors
- Error creating temporary file for upload
- failed to write temp known_hosts file
- Cannot quote scp command, target platform unknown
- Connection Error: StatusCode
- connection type ' ' not supported
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/c7e8969aaa7cdd6d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/communicator/ssh/provisioner.go:339
password string
sshAgent *sshAgent
certificate string
user string
host string
hostKey string
}
func buildSSHClientConfig(opts sshClientConfigOpts) (*ssh.ClientConfig, error) {
hkCallback := ssh.InsecureIgnoreHostKey()
if opts.hostKey != "" {
// The knownhosts package only takes paths to files, but terraform
// generally wants to handle config data in-memory. Rather than making
// the known_hosts file an exception, write out the data to a temporary
// file to create the HostKeyCallback.
tf, err := ioutil.TempFile("", "tf-known_hosts")
if err != nil {
return nil, fmt.Errorf("failed to create temp known_hosts file: %s", err)
}
defer tf.Close()
defer os.RemoveAll(tf.Name())
// we mark this as a CA as well, but the host key fallback will still
// use it as a direct match if the remote host doesn't return a
// certificate.
if _, err := tf.WriteString(fmt.Sprintf("@cert-authority %s %s\n", opts.host, opts.hostKey)); err != nil {
return nil, fmt.Errorf("failed to write temp known_hosts file: %s", err)
}
tf.Sync()
hkCallback, err = knownhosts.New(tf.Name())
if err != nil {
return nil, err
}
}
View on GitHub (pinned to d32a084675)