{"record":{"id":"8f2189b936ac6cf5","repo":"kubernetes/kops","slug":"error-opening-q-w","errorCode":null,"errorMessage":"error opening %q: %w","messagePattern":"error opening %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/otel/otlptracefile/writer.go","lineNumber":46,"sourceCode":"\t\"google.golang.org/protobuf/proto\"\n\t\"k8s.io/kops/pkg/otel/otlptracefile/pb\"\n)\n\ntype writer struct {\n\tfileMutex sync.Mutex\n\tf         *os.File\n\n\ttypeCodesMutex sync.Mutex\n\tnextTypeCode   TypeCode\n\ttypeCodes      map[string]TypeCode\n}\n\ntype TypeCode uint32\n\nfunc newWriter(cfg Config) (*writer, error) {\n\tf, err := os.OpenFile(cfg.path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening %q: %w\", cfg.path, err)\n\t}\n\tw := &writer{\n\t\tf: f,\n\t}\n\tw.nextTypeCode = 32\n\tw.typeCodes = make(map[string]TypeCode)\n\tw.recordWellKnownType(pb.WellKnownTypeCode_WellKnownTypeCode_ObjectType, &pb.ObjectType{})\n\n\treturn w, nil\n}\n\n// writeTraces is called by the otel libraries to write a set of trace records.\nfunc (w *writer) writeTraces(ctx context.Context, req *coltracepb.ExportTraceServiceRequest) error {\n\treturn w.writeObject(ctx, req)\n}\n\n// codeForType returns the integer code value for objects of obj.\n// 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.","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/otel/otlptracefile/writer.go#L28-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\ncfg := Config{Path: \"/var/log/traces.bin\"} // dir may not exist\n// after\nos.MkdirAll(\"/var/log\", 0755)\ncfg := Config{Path: \"/var/log/traces.bin\"}","handlingStrategy":"validation","validationCode":"if dir := filepath.Dir(cfg.Path); dir != \"\" {\n    if err := os.MkdirAll(dir, 0755); err != nil { return err }\n}\nif fi, err := os.Stat(cfg.Path); err == nil && fi.IsDir() {\n    return fmt.Errorf(\"%s is a directory\", cfg.Path)\n}","typeGuard":null,"tryCatchPattern":"if err := client.Start(ctx); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) { /* fix path/permissions before retry */ }\n    return err\n}","preventionTips":["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"],"tags":["opentelemetry","file-io","permissions"],"backgroundTag":"file-open-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}