containerd/containerd · error

failed to apply config opt: %w

Error message

failed to apply config opt: %w

What it means

The LCOW differ's Apply runs each functional option (diff.ApplyOpt) against an ApplyConfig before walking layer mounts. If any opt returns an error, Apply aborts with this wrapped message. The underlying error identifies which option failed.

Source

Thrown at plugins/diff/lcow/lcow.go:114

// provided mounts. Archive content will be extracted and decompressed if
// necessary.
func (s windowsLcowDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt) (d ocispec.Descriptor, err error) {
	t1 := time.Now()
	defer func() {
		if err == nil {
			log.G(ctx).WithFields(log.Fields{
				"d":      time.Since(t1),
				"digest": desc.Digest,
				"size":   desc.Size,
				"media":  desc.MediaType,
			}).Debugf("diff applied")
		}
	}()

	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 := mountsToLayerAndParents(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()

	processor := diff.NewProcessorChain(desc.MediaType, content.NewReader(ra))
	for {
		if processor, err = diff.GetProcessor(ctx, processor, config.ProcessorPayloads); err != nil {
			return emptyDesc, fmt.Errorf("failed to get stream processor for %s: %w", desc.MediaType, err)

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Inspect the wrapped error to find the failing opt
  2. Remove or fix the offending ApplyOpt in the opts list
  3. Use the differ via containerd's standard diff service so opts are constructed correctly

Example fix

// before
desc, err := differ.Apply(ctx, desc, mounts, customOpt)
// after
desc, err := differ.Apply(ctx, desc, mounts) // rely on default opts
Defensive patterns

Strategy: try-catch

Try / catch

desc, err := differ.Apply(ctx, desc, mounts, opts...)
if err != nil {
    if strings.Contains(err.Error(), "failed to apply config opt") {
        log.Error("bad apply option", "cause", errors.Unwrap(err))
        // retry without custom opts
        desc, err = differ.Apply(ctx, desc, mounts)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the LCOW differ's Apply(ctx, desc, mounts, opts...) with opts that fail — e.g. a config opt provided by containerd that errors when parsed against the descriptor or snapshot mounts.

Common situations: Passing processor/metadata opts built for another differ; malformed WithProcessorPayloads data; callers constructing opts manually with invalid values.

Related errors


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