{"record":{"id":"3373c2c48fe77ce0","repo":"hashicorp/terraform","slug":"cannot-create-temporary-file-to-update-credentials","errorCode":null,"errorMessage":"cannot create temporary file to update credentials: %s","messagePattern":"cannot create temporary file to update credentials: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/cliconfig/credentials.go","lineNumber":400,"sourceCode":"\t}\n\n\tnewSrc, err := json.MarshalIndent(raw, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot serialize updated credentials file: %s\", err)\n\t}\n\n\t// Now we'll write our new content over the top of the existing file.\n\t// Because we updated the data structure surgically here we should not\n\t// have disturbed the meaning of any other content in the file, but it\n\t// might have a different JSON layout than before.\n\t// We'll create a new file with a different name first and then rename\n\t// it over the old file in order to make the change as atomically as\n\t// the underlying OS/filesystem will allow.\n\t{\n\t\tdir, file := filepath.Split(filename)\n\t\tf, err := ioutil.TempFile(dir, file)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot create temporary file to update credentials: %s\", err)\n\t\t}\n\t\ttmpName := f.Name()\n\t\tmoved := false\n\t\tdefer func(f *os.File, name string) {\n\t\t\t// Remove the temporary file if it hasn't been moved yet. We're\n\t\t\t// ignoring errors here because there's nothing we can do about\n\t\t\t// them anyway.\n\t\t\tif !moved {\n\t\t\t\tos.Remove(name)\n\t\t\t}\n\t\t}(f, tmpName)\n\n\t\t// Write the credentials to the temporary file, then immediately close\n\t\t// it, whether or not the write succeeds.\n\t\t_, err = f.Write(newSrc)\n\t\tf.Close()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot write to temporary file %s: %s\", tmpName, err)","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/cliconfig/credentials.go#L382-L418","documentation":"Thrown when ioutil.TempFile fails to create a scratch file in the same directory as the credentials file. Terraform writes new credentials via a temp-file + atomic rename pattern; the temp file is created in filepath.Split(filename)'s directory so the rename is on the same filesystem. A failure here means the directory itself is not writable or cannot allocate a new entry.","triggerScenarios":"The credentials directory (e.g. ~/.terraform.d/) does not exist, is read-only, has no free inodes, or the filesystem is mounted read-only. Also when the directory path is invalid (empty, a file, or otherwise).","commonSituations":"HOME is unset or points somewhere non-writable (CI containers, restricted service accounts); the .terraform.d directory was deleted or chmod'd to 0500 owned by another user; a read-only root filesystem in a hardened container; disk full / out of inodes.","solutions":["Ensure the credentials directory exists and is writable: `mkdir -p ~/.terraform.d && chmod u+w ~/.terraform.d`.","Verify HOME is set to a writable location: `echo $HOME` and `touch $HOME/.terraform.d/.write-test`.","Check disk and inode usage: `df -h <dir>` and `df -i <dir>`.","If using TF_CLI_CONFIG_FILE, confirm its parent directory is writable and on a writable filesystem."],"exampleFix":"// before: HOME=/readonly, .terraform.d not writable\n// $ export HOME=/home/$USER\n// $ mkdir -p $HOME/.terraform.d && chmod 700 $HOME/.terraform.d\n// after: terraform login creates the temp file and completes the atomic rename","handlingStrategy":"validation","validationCode":"func ensureCredsDirWritable(filename string) error {\n    dir, _ := filepath.Split(filename)\n    if dir == \"\" { dir = \".\" }\n    fi, err := os.Stat(dir)\n    if err != nil {\n        return os.MkdirAll(dir, 0700)\n    }\n    if !fi.IsDir() {\n        return fmt.Errorf(\"%s is not a directory\", dir)\n    }\n    probe, err := os.CreateTemp(dir, \".perm-test-*\")\n    if err != nil {\n        return fmt.Errorf(\"cannot create files in %s: %w\", dir, err)\n    }\n    probe.Close(); os.Remove(probe.Name())\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure HOME / TF_CLI_CONFIG_FILE parent dir exists and is writable before running login.","In containers, mount a writable volume at $HOME.","Avoid pointing credentials at a read-only filesystem."],"tags":["credentials","filesystem","permissions","atomic-write","config"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}