containerd/containerd · error

failed to apply config opt: %w

Error message

failed to apply config opt: %w

What it means

Apply first runs each provided ApplyOpt (diff.ApplyConfig option) against a fresh diff.ApplyConfig. If any option function returns an error, it is wrapped as "failed to apply config opt" and Apply aborts before doing any layer work. The wrapped error comes from the option itself (e.g. an invalid window/block-size config, filesystem option rejection, or a context cancellation inside the opt).

Source

Thrown at plugins/diff/erofs/differ.go:172

		return emptyDesc, fmt.Errorf("unsupported media type: %s", desc.MediaType)
	}

	switch {
	case fastcopy:
		mode = "fastcopy"
	case native:
		mode = "native"
	case s.enableTarIndex:
		mode = "tar-index"
	default:
		mode = "convert"
	}
	span.SetAttributes(tracing.Attribute("erofs.apply.mode", mode))

	var config diff.ApplyConfig
	for _, o := range opts {
		if err := o(ctx, desc, &config); err != nil {
			return emptyDesc, fmt.Errorf("failed to apply config opt: %w", err)
		}
	}

	layer, err := erofsutils.MountsToLayer(mounts)
	if err != nil {
		return emptyDesc, err
	}

	ra, err := s.store.ReaderAt(ctx, desc)
	if err != nil {
		return emptyDesc, fmt.Errorf("failed to get reader from content store: %w", err)
	}
	defer ra.Close()

	layerBlobPath := path.Join(layer, "layer.erofs")
	// Allow copy file range when there is an uncompressed native EROFS layer
	if fastcopy {
		f, err := os.Create(layerBlobPath)

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Read the wrapped cause in the error (%w) — it names the failing option; correct that option's value or remove it.
  2. Log/inspect the opts being passed to Apply and confirm each is valid for this differ version.
  3. Check host kernel support for the EROFS features requested by the opts (e.g. zstd decompression, chunk dedup) — upgrade the kernel or drop those opts.
  4. Retry after fixing; if ctx is cancelled, re-create the context with a proper timeout.

Example fix

// before
differ.Apply(ctx, sn, mounts, desc, diff.WithWindow(0)) // invalid value rejected by opt
// after
differ.Apply(ctx, sn, mounts, desc, diff.WithWindow(32<<20)) // valid config value
Defensive patterns

Strategy: try-catch

Validate before calling

var cfg diff.ApplyConfig
for _, o := range opts {
    if err := o(ctx, desc, &cfg); err != nil {
        return fmt.Errorf("invalid apply opt for %s: %w", desc.MediaType, err)
    }
}
// opts validated; safe to call Apply with the same opts

Type guard

func optsValid(ctx context.Context, desc ocispec.Descriptor, opts ...diff.ApplyOpt) bool {
    var cfg diff.ApplyConfig
    for _, o := range opts {
        if err := o(ctx, desc, &cfg); err != nil { return false }
    }
    return true
}

Try / catch

desc, err := differ.Apply(ctx, sn, mounts, layerDesc, opts...)
if err != nil && strings.Contains(err.Error(), "failed to apply config opt") {
    // drop custom opts and retry with defaults
    desc, err = differ.Apply(ctx, sn, mounts, layerDesc)
}

Prevention

When it happens

Trigger: Passing a diff.WithApplyOpt/ApplyOpt to Apply (directly or via CRI/pull configuration, e.g. erofs-specific opts like chunk/block size, compress hints, or remap-ids options) whose function validates inputs and fails; ctx already cancelled; passing an opt meant for a different differ.

Common situations: Misconfigured apply options in the CRI/pull config (unsupported values for the mounted EROFS filesystem); applying opts that require kernel/filesystem features the host lacks; a bug or version mismatch between the caller constructing opts and the plugin version interpreting them.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/cc33e567ce3ee1ca. Report an issue: GitHub.