cilium/cilium · error
failed to compile template program: %w
Error message
failed to compile template program: %w
What it means
After generating the header, build() invokes compileDatapath to run the clang/LLVM toolchain over the template. Any failure there is wrapped as 'failed to compile template program'. The wrapped error typically includes the compiler's stderr via compileDatapath.
Source
Thrown at pkg/datapath/loader/cache.go:157
if err := os.MkdirAll(dir.Output, defaults.StateDirRights); err != nil {
return "", fmt.Errorf("failed to create template directory: %w", err)
}
headerPath := filepath.Join(dir.State, common.CHeaderFileName)
f, err := os.Create(headerPath)
if err != nil {
return "", fmt.Errorf("failed to open template header for writing: %w", err)
}
defer f.Close()
if err = o.Writer.WriteEndpointConfig(f, cfg); err != nil {
return "", fmt.Errorf("failed to write template header: %w", err)
}
stats.BpfCompilation.Start()
err = compileDatapath(ctx, o.logger, dir, isHost)
stats.BpfCompilation.End(err == nil)
if err != nil {
return "", fmt.Errorf("failed to compile template program: %w", err)
}
o.logger.Info(
"Compiled new BPF template",
logfields.Path, objectPath,
logfields.BPFCompilationTime, stats.BpfCompilation.Total(),
)
return objectPath, nil
}
// fetchOrCompile attempts to fetch the path to the datapath object
// corresponding to the provided endpoint configuration, or if this
// configuration is not yet compiled, compiles it. It will block if multiple
// threads attempt to concurrently fetchOrCompile a template binary for the
// same set of EndpointConfiguration.
//
// Returns a copy of the compiled and parsed ELF and a hash identifying a cached entry.View on GitHub (pinned to ac7b90affa)
Solutions
- Read compiler stderr in the wrapped error for the exact C compile failure
- Verify clang/llvm versions installed (clang -version) match requirements
- Check kernel BPF config (CONFIG_BPF, CONFIG_BPF_SYSCALL, cgroup/vlan features)
- Increase context timeout if compilation was cancelled, and recompile
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: clang present and new enough
out, err := exec.Command("clang", "--version").Output()
if err != nil {
return fmt.Errorf("clang not installed: %w", err)
}
if !minLLVMVersion(string(out)) {
return errors.New("clang too old for BPF compilation")
} Try / catch
if err := compileDatapath(ctx, logger, dir, isHost); err != nil {
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
return retryWithLongerTimeout(ctx)
}
log.Errorf("compile failed: %v (stderr in error chain)", err)
return err
} Prevention
- Pin the required clang/LLVM version in images
- Compile with a generous context timeout
- Check kernel BPF config options before rollout
- Capture and persist compiler stderr for debugging
When it happens
Trigger: compileDatapath returning non-nil: clang not found or wrong version, kernel headers mismatch, compilation error in generated C, context cancelled during compile, or output object not produced.
Common situations: Missing clang >= required version in the container image; kernel BPF feature detection mismatch (CONFIG_* options); custom BPF source mount issues; context timeout killing the compile ('signal: killed').
Related errors
- Failed to compile %s: %w
- failed to open template header for writing: %w
- failed to write template header: %w
- making Blocks for ProgramSpec %s: %w
- Unable to determine if BPF_FIB_LOOKUP_SRC is supported
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/013d186d7ca6a8f7.
Report an issue: GitHub.