{"record":{"id":"a3d7c3cd0896979e","repo":"grpc/grpc-go","slug":"failed-to-create-temp-file-v","errorCode":null,"errorMessage":"failed to create temp file: %v","messagePattern":"failed to create temp file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"binarylog/sink.go","lineNumber":65,"sourceCode":"\t// is not specified, but should have sufficient information to rebuild the\n\t// entry. Some options are: proto bytes, or proto json.\n\t//\n\t// Note this function needs to be thread-safe.\n\tWrite(*binlogpb.GrpcLogEntry) error\n\t// Close closes this sink and cleans up resources (e.g. the flushing\n\t// goroutine).\n\tClose() error\n}\n\n// NewTempFileSink creates a temp file and returns a Sink that writes to this\n// file.\nfunc NewTempFileSink() (Sink, error) {\n\t// Two other options to replace this function:\n\t// 1. take filename as input.\n\t// 2. export NewBufferedSink().\n\ttempFile, err := os.CreateTemp(\"/tmp\", \"grpcgo_binarylog_*.txt\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create temp file: %v\", err)\n\t}\n\treturn iblog.NewBufferedSink(tempFile), nil\n}\n","sourceCodeStart":47,"sourceCodeEnd":69,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/binarylog/sink.go#L47-L69","documentation":"binarylog.NewTempFileSink() creates a temporary file under /tmp via os.CreateTemp(\"/tmp\", \"grpcgo_binarylog_*.txt\") to serve as a binary log destination (sink.go:63). If the OS call fails, the underlying error is wrapped and returned. The sink is used by the binary logging feature (env vars GRPC_BINARY_LOG_FILTER / GRPC_BINARY_LOG_LOGGER).","triggerScenarios":"Calling binarylog.NewTempFileSink() when /tmp does not exist, is not writable, is full (ENOSPC), or the process lacks permissions. Also when the open-file / inode limit is exhausted.","commonSituations":"Running in a hardened container or read-only filesystem where /tmp is missing or mounted read-only; a full disk; exceeding the per-process file descriptor limit; SELinux/AppArmor denying temp file creation.","solutions":["Ensure /tmp exists and is writable by the process, or remount it read-write in the container.","Free disk space or raise the file-descriptor / inode limits (ulimit -n).","Switch to a custom Sink implementation (implement the Sink interface) writing to a path you control instead of NewTempFileSink."],"exampleFix":"// before\nsink, err := binarylog.NewTempFileSink()\n// after (write to a controlled path)\nf, err := os.OpenFile(\"/var/log/grpc/binlog.txt\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)\nif err != nil { return err }\nsink := iblog.NewBufferedSink(f)","handlingStrategy":"try-catch","validationCode":"// Check /tmp writability before relying on NewTempFileSink.\nfunc tmpWritable() bool {\n    f, err := os.CreateTemp(\"/tmp\", \"probe_*\")\n    if err != nil { return false }\n    f.Close(); os.Remove(f.Name()); return true\n}","typeGuard":null,"tryCatchPattern":"sink, err := binarylog.NewTempFileSink()\nif err != nil {\n    log.Printf(\"temp sink unavailable (%v); falling back to custom sink\", err)\n    f, _ := os.OpenFile(\"/var/log/grpc/binlog.txt\", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)\n    sink = iblog.NewBufferedSink(f)\n}","preventionTips":["In containers, mount a writable /tmp or tmpfs.","Prefer a custom Sink pointing at a path you own over NewTempFileSink in production.","Monitor disk free space and open-fd limits where binary logging runs."],"tags":["go","grpc","logging","filesystem","environment"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}