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
- Read the wrapped canInstrument reason and restrict the plugin to the attachment contexts it supports
- Update the plugin so its hook targets match programs instrumentable in this context
- Adjust the plugin's registration/configuration so it is only loaded for valid attachment kinds
- If the hook is optional, switch the plugin to a best-effort AttachmentPolicy
- 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
- Register plugins only for the attachment kinds whose programs they hook
- Keep plugin hook targets within programs whose sections/types canInstrument allows
- Test plugin+agent integration per attachment kind in CI
- Re-check canInstrument rules when moving programs between sections
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
- preparing hooks: %w
- loading hooks: %w
- %s: PrepareCollection(): %w
- %s: PrepareCollection(): target program \"%s\" does not exis
- %s: PrepareCollection(): invalid hook type %v
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/a22b91feff78e915.
Report an issue: GitHub.