{"record":{"id":"c8e08a6ab59802d6","repo":"hashicorp/terraform","slug":"cannot-write-to-temporary-file-s-s","errorCode":null,"errorMessage":"cannot write to temporary file %s: %s","messagePattern":"cannot write to temporary file (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/cliconfig/credentials.go","lineNumber":418,"sourceCode":"\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)\n\t\t}\n\n\t\t// Temporary file now replaces the original file, as atomically as\n\t\t// possible. (At the very least, we should not end up with a file\n\t\t// containing only a partial JSON object.)\n\t\terr = replacefile.AtomicRename(tmpName, filename)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to replace %s with temporary file %s: %s\", filename, tmpName, err)\n\t\t}\n\n\t\t// Credentials file should be readable only by its owner. (This may\n\t\t// not be effective on all platforms, but should at least work on\n\t\t// Unix-like targets and should be harmless elsewhere.)\n\t\tif err := os.Chmod(filename, 0600); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot set mode for credentials file %s: %s\", filename, err)\n\t\t}\n\n\t\tmoved = true","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/cliconfig/credentials.go#L400-L436","documentation":"Thrown when f.Write(newSrc) fails while writing the serialized credentials to the temp file. The file was successfully created (TempFile passed) but writing the JSON bytes failed — typically due to disk-full, quota, or an I/O error on the underlying device. The temp file is closed and the deferred cleanup removes it.","triggerScenarios":"Disk runs out of space mid-write; a disk quota (user or filesystem) is exceeded; the device returns EIO; on some network filesystems the connection drops during write.","commonSituations":"CI runner out of disk; a small tmpfs mounted at HOME; NFS/CIFS hiccup; a previous near-full condition that this write tips over.","solutions":["Free space in the credentials directory: `df -h <dir>`; remove unneeded files.","Check user/filesystem quotas if applicable (`quota -u $USER`).","If on a network filesystem, retry; if persistent, point TF_CLI_CONFIG_FILE / HOME at a local directory.","Confirm the device is healthy (`dmesg | tail` for I/O errors)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"func freeSpaceOK(dir string) error {\n    var s syscall.Statfs_t\n    if err := syscall.Statfs(dir, &s); err != nil { return err }\n    if s.Bavail*uint64(s.Bsize) < uint64(1024) {\n        return fmt.Errorf(\"insufficient free space in %s\", dir)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep free disk space above a small floor in the credentials directory.","Retry once on transient I/O errors before surfacing to the user.","Avoid network filesystems for credentials when possible."],"tags":["credentials","filesystem","disk-full","io-error","atomic-write"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}