kubernetes/kops · error
error opening %q: %w
Error message
error opening %q: %w
What it means
newWriter opens (creating or truncating) the trace output file at cfg.path with os.OpenFile(O_RDWR|O_CREATE|O_TRUNC, 0600). Any OS-level failure opening that file is wrapped as "error opening %q: %w" and propagated to Start.
Source
Thrown at pkg/otel/otlptracefile/writer.go:46
"google.golang.org/protobuf/proto"
"k8s.io/kops/pkg/otel/otlptracefile/pb"
)
type writer struct {
fileMutex sync.Mutex
f *os.File
typeCodesMutex sync.Mutex
nextTypeCode TypeCode
typeCodes map[string]TypeCode
}
type TypeCode uint32
func newWriter(cfg Config) (*writer, error) {
f, err := os.OpenFile(cfg.path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return nil, fmt.Errorf("error opening %q: %w", cfg.path, err)
}
w := &writer{
f: f,
}
w.nextTypeCode = 32
w.typeCodes = make(map[string]TypeCode)
w.recordWellKnownType(pb.WellKnownTypeCode_WellKnownTypeCode_ObjectType, &pb.ObjectType{})
return w, nil
}
// writeTraces is called by the otel libraries to write a set of trace records.
func (w *writer) writeTraces(ctx context.Context, req *coltracepb.ExportTraceServiceRequest) error {
return w.writeObject(ctx, req)
}
// codeForType returns the integer code value for objects of obj.
// If this is the first time we've seen the type, this method will assign a code value, write it to the file and return it.View on GitHub (pinned to 4c8573c808)
Solutions
- Create the parent directory of cfg.path before starting the exporter (os.MkdirAll).
- Ensure the process user has write permission (mode 0600 is applied; directory needs write+execute).
- Point cfg.path at a mounted, writable volume; check it is not a directory.
- Check filesystem is writable (not read-only, not full).
Example fix
// before
cfg := Config{Path: "/var/log/traces.bin"} // dir may not exist
// after
os.MkdirAll("/var/log", 0755)
cfg := Config{Path: "/var/log/traces.bin"} Defensive patterns
Strategy: validation
Validate before calling
if dir := filepath.Dir(cfg.Path); dir != "" {
if err := os.MkdirAll(dir, 0755); err != nil { return err }
}
if fi, err := os.Stat(cfg.Path); err == nil && fi.IsDir() {
return fmt.Errorf("%s is a directory", cfg.Path)
} Try / catch
if err := client.Start(ctx); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) { /* fix path/permissions before retry */ }
return err
} Prevention
- Create the output directory during setup
- Run the exporter as a user with write access to the path
- Mount a writable volume for trace files in containers
- Avoid paths on read-only or near-full filesystems
When it happens
Trigger: cfg.path points to a non-existent directory; the path exists but is a directory; missing write permission; read-only filesystem or full disk causing unexpected open failure.
Common situations: Misconfigured OTEL file exporter path in a container (path not mounted/volume not writable); running nodeup/exporter as a non-root user writing to a root-only directory; SELinux/AppArmor blocking the path.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8f2189b936ac6cf5.
Report an issue: GitHub.