cilium/cilium · error

failed to apply option: %w

Error message

failed to apply option: %w

What it means

NewExporter (pkg/hubble/exporter/exporter.go:68) starts from DefaultOptions and applies each Option in order; if any option function returns an error, construction aborts immediately with this wrapper so the underlying option failure is preserved. Options here include allow/deny filters and writer/encoder setup, which validate their arguments before mutating opts.

Source

Thrown at pkg/hubble/exporter/exporter.go:68

var _ FlowLogExporter = (*exporter)(nil)

// exporter is an implementation of OnDecodedEvent interface that writes Hubble events to a file.
type exporter struct {
	logger     *slog.Logger
	encoder    Encoder
	writer     io.WriteCloser
	flow       *flowpb.Flow
	aggregator *AggregatorRunner
	opts       Options
}

// NewExporter initializes an
// NOTE: Stopped instances cannot be restarted and should be re-created.
func NewExporter(logger *slog.Logger, options ...Option) (*exporter, error) {
	opts := DefaultOptions // start with defaults
	for _, opt := range options {
		if err := opt(&opts); err != nil {
			return nil, fmt.Errorf("failed to apply option: %w", err)
		}
	}
	logger.Info(
		"Configuring Hubble event exporter",
		logfields.Options, opts,
	)
	return newExporter(logger, opts)
}

// newExporter let's you supply your own WriteCloser for tests.
func newExporter(logger *slog.Logger, opts Options) (*exporter, error) {
	writer, err := opts.NewWriterFunc()()
	if err != nil {
		return nil, fmt.Errorf("failed to create writer: %w", err)
	}
	encoder, err := opts.NewEncoderFunc()(writer)
	if err != nil {
		writer.Close()

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Read the wrapped inner error to identify which option failed and why.
  2. Fix the filter expression/arguments passed to WithAllowList/WithDenyList (validate filters before startup).
  3. Test each option independently by calling it against DefaultOptions in a unit test.
  4. If a custom Option fails, correct its validation or the inputs it receives.

Example fix

// before
fl, err := flow.ParseFlows([]string{"verdict=DROPPED tcp-port="}) // bad filter
exp, err := exporter.NewExporter(logger, exporter.WithAllowList(logger, fl))

// after
fl, err := flow.ParseFlows([]string{"verdict=DROPPED"})
if err != nil { log.Fatal(err) }
exp, err := exporter.NewExporter(logger, exporter.WithAllowList(logger, fl))
Defensive patterns

Strategy: validation

Validate before calling

opts := exporter.DefaultOptions
for _, opt := range options {
    if err := opt(&opts); err != nil {
        return fmt.Errorf("pre-flight option check failed: %w", err)
    }
}

Try / catch

exp, err := exporter.NewExporter(logger, opts...)
if err != nil {
    if strings.Contains(err.Error(), "failed to apply option") {
        log.Errorf("invalid exporter option/filter configuration: %v", err)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Any Option passed to NewExporter returns a non-nil error — typically an invalid filter expression in WithAllowList/WithDenyList (unparseable flow filter), or a custom Option validating its inputs and failing.

Common situations: Passing a malformed Hubble flow filter (bad CEL expression, unknown field) to the allow/deny list; wiring flags into filters where an empty or typo'd value slips through; a custom Option with its own validation returning an error.

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/c1bdee0dbb679d32. Report an issue: GitHub.