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

  1. Create the parent directory of cfg.path before starting the exporter (os.MkdirAll).
  2. Ensure the process user has write permission (mode 0600 is applied; directory needs write+execute).
  3. Point cfg.path at a mounted, writable volume; check it is not a directory.
  4. 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

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.