grpc/grpc-go · error
failed to create temp file: %v
Error message
failed to create temp file: %v
What it means
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).
Source
Thrown at binarylog/sink.go:65
// is not specified, but should have sufficient information to rebuild the
// entry. Some options are: proto bytes, or proto json.
//
// Note this function needs to be thread-safe.
Write(*binlogpb.GrpcLogEntry) error
// Close closes this sink and cleans up resources (e.g. the flushing
// goroutine).
Close() error
}
// NewTempFileSink creates a temp file and returns a Sink that writes to this
// file.
func NewTempFileSink() (Sink, error) {
// Two other options to replace this function:
// 1. take filename as input.
// 2. export NewBufferedSink().
tempFile, err := os.CreateTemp("/tmp", "grpcgo_binarylog_*.txt")
if err != nil {
return nil, fmt.Errorf("failed to create temp file: %v", err)
}
return iblog.NewBufferedSink(tempFile), nil
}
View on GitHub (pinned to 03255a9237)
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.
Example fix
// before
sink, err := binarylog.NewTempFileSink()
// after (write to a controlled path)
f, err := os.OpenFile("/var/log/grpc/binlog.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil { return err }
sink := iblog.NewBufferedSink(f) Defensive patterns
Strategy: try-catch
Validate before calling
// Check /tmp writability before relying on NewTempFileSink.
func tmpWritable() bool {
f, err := os.CreateTemp("/tmp", "probe_*")
if err != nil { return false }
f.Close(); os.Remove(f.Name()); return true
} Try / catch
sink, err := binarylog.NewTempFileSink()
if err != nil {
log.Printf("temp sink unavailable (%v); falling back to custom sink", err)
f, _ := os.OpenFile("/var/log/grpc/binlog.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
sink = iblog.NewBufferedSink(f)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- token file access error
- cannot have a leading slash
- / must come in between service and method, only one /
- method name must be non empty
- cannot have exclude and a '*' wildcard
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/a3d7c3cd0896979e.
Report an issue: GitHub.