cilium/cilium · error

building BTF spec: %w

Error message

building BTF spec: %w

What it means

After all maps and variables have been added, runTypes calls bb.Spec() to materialize the merged, deduplicated BTF spec used for type queries. This error wraps a failure producing that spec. Since inputs were already accepted individually, failure here indicates the accumulated type collection is internally inconsistent (e.g. irreconcilable duplicates) or the builder rejected the merge.

Source

Thrown at tools/dpgen/types.go:74

			}
		}

		for _, v := range sorted(cs.Variables) {
			// We can skip aux variables as they are only used from the BPF side.
			if v.SectionName == auxSection {
				continue
			}
			if err := addVariableType(bb, added, v); err != nil {
				return fmt.Errorf("adding type for variable %s: %w", v.Name, err)
			}
		}
	}

	// Pull a BTF spec out of the builder, allowing us to query the merged type
	// collection.
	spec, err := bb.Spec()
	if err != nil {
		return fmt.Errorf("building BTF spec: %w", err)
	}

	b := bytes.Buffer{}
	if err := writeHeader(&b, typesOpts.goPkg, []string{"structs"}); err != nil {
		return fmt.Errorf("writing header: %w", err)
	}

	gf := btf.GoFormatter{Identifier: camelCase}
	for t := range sortedSeq(added.Members()) {
		// Look up all added root types by name to: 1. avoid emitting type decls for
		// embedded types, and 2. ensure all types with the same name deduplicated
		// into one concrete type. This lookup will fail if there are multiple
		// incompatible candidate types with the same name across objects.
		typ, err := spec.AnyTypeByName(t)
		if err != nil {
			return fmt.Errorf("getting BTF type %v: %w", t, err)
		}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Rebuild all globbed BPF objects from one consistent set of headers so same-name types are identical.
  2. Narrow the glob to the objects actually needed, removing the one introducing conflicting types.
  3. Upgrade cilium/ebpf; builder/dedup bugs are fixed over time.
  4. Bisect the object set: run dpgen -types on halves of the glob to isolate the conflicting object.
  5. Inspect `bpftool btf dump file <o>` output of each object for duplicate type names with differing definitions.
Defensive patterns

Strategy: try-catch

Try / catch

if err := runTypes(...); err != nil {
    if strings.Contains(err.Error(), "building BTF spec") {
        return fmt.Errorf("merged BTF inconsistent; rebuild all objects from one header set or narrow the glob: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: dpgen -types with a set of ELF objects whose combined added types cannot be turned into a single btf.Spec by btf.Builder.Spec().

Common situations: Two globbed objects contribute same-name but structurally different types that deduplication could not collapse; a very large or malformed set of types triggering a builder limitation; version mismatch between the objects' BTF and the cilium/ebpf builder expectations.

Related errors


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