cilium/cilium · error

%s: PrepareCollection(): \"%s\": %w

Error message

%s: PrepareCollection(): \"%s\": %w

What it means

For each hook a plugin requests, prepareCollection calls canInstrument(ps, attachmentContext) to check the program is instrumentable in this attachment context (type/attach-type/section constraints). A failed check is recorded as '<plugin>: PrepareCollection(): "X": <reason>' and fails the load.

Source

Thrown at pkg/datapath/loader/plugins.go:344

					logfields.CiliumDatapathPluginName, r.plugin.Name(),
					logfields.Error, r.err,
				)
			}

			continue
		} else {
			responses[r.plugin.Name()] = r.resp
		}

	process_hooks:
		for _, h := range r.resp.Hooks {
			ps := spec.Programs[h.Target]
			if ps == nil {
				err = errors.Join(err, fmt.Errorf("%s: PrepareCollection(): target program \"%s\" does not exist in the collection spec", r.plugin.Name(), h.Target))

				continue
			} else if canErr := canInstrument(ps, attachmentContext); canErr != nil {
				err = errors.Join(err, fmt.Errorf("%s: PrepareCollection(): \"%s\": %w", r.plugin.Name(), h.Target, canErr))

				continue
			}

			if h.Type != datapathplugins.HookType_PRE && h.Type != datapathplugins.HookType_POST {
				err = errors.Join(err, fmt.Errorf("%s: PrepareCollection(): invalid hook type %v", r.plugin.Name(), h.Type))

				continue
			}

			hooksSpec.hook(ps.Name, h.Type).addNode(r.plugin.Name())

			for _, c := range h.Constraints {
				otherPlugin := lnc.Plugins[c.Plugin]
				if otherPlugin == nil {
					continue
				}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Read the wrapped canInstrument reason and restrict the plugin to the attachment contexts it supports
  2. Update the plugin so its hook targets match programs instrumentable in this context
  3. Adjust the plugin's registration/configuration so it is only loaded for valid attachment kinds
  4. If the hook is optional, switch the plugin to a best-effort AttachmentPolicy
  5. Update the datapath program's section/type if it was unintentionally changed
Defensive patterns

Strategy: validation

Validate before calling

func canAttachToContext(ps *ebpf.ProgramSpec, ctx *AttachmentContext) error {
    switch ctx.Kind {
    case AttachmentEndpoint:
        if !endpointInstrumentable(ps) { return fmt.Errorf("program %q not instrumentable for endpoints", ps.Name) }
    case AttachmentHost:
        if !hostInstrumentable(ps) { return fmt.Errorf("program %q not instrumentable for host netdev", ps.Name) }
    }
    return nil
}

Prevention

When it happens

Trigger: A plugin requests a hook on a program that exists in the spec but canInstrument rejects it for this attachmentContext — e.g. hooking a program type not allowed for that context, attaching to a socket-load or unrelated program section, or an attachment kind the program doesn't support.

Common situations: Plugin registered for endpoint attachments tries to hook host-netdev-only programs; plugin not updated after the datapath moved a program to a different section/type; plugin enabled globally but only valid for specific attachment kinds.

Related errors


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