mudler/LocalAI · critical

trellis2 ABI mismatch: library reports %d, backend built for

Error message

trellis2 ABI mismatch: library reports %d, backend built for %d

What it means

Startup panic of the Go trellis2 backend: after dlopen of the trellis2 library succeeds, the C API's reported ced-style ABI version (t2AbiVersion()) does not equal the abiVersion constant the Go binary was compiled against. This guard exists because purego has no compile-time type checking — a mismatched struct layout would cause memory corruption, so the backend refuses to start.

Source

Thrown at backend/go/trellis2cpp/main.go:42

	// run.sh selects the CPU-variant directory and points TRELLIS2_LIBRARY at it.
	libName := os.Getenv("TRELLIS2_LIBRARY")
	if libName == "" {
		if runtime.GOOS == "darwin" {
			libName = "./variants/fallback/libtrellis2.dylib"
		} else {
			libName = "./variants/fallback/libtrellis2.so"
		}
	}

	lib, err := purego.Dlopen(libName, purego.RTLD_NOW|purego.RTLD_GLOBAL)
	if err != nil {
		panic(err)
	}

	registerLibFuncs(lib)

	if got := t2AbiVersion(); got != abiVersion {
		panic(fmt.Sprintf("trellis2 ABI mismatch: library reports %d, backend built for %d", got, abiVersion))
	}

	flag.Parse()

	if err := grpc.StartServer(*addr, &Trellis2{}); err != nil {
		panic(err)
	}
}

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Rebuild the trellis2 native library and the Go backend from the same source revision so the ABI constant matches
  2. Remove stale variants/fallback/libtrellis2.so copies that shadow the fresh build
  3. Check backend release notes/changelog for ABI-breaking changes and update both components together
  4. If vendoring, pin both the lib and the Go module to the same release tag

Example fix

# before: stale lib shadowing fresh build
ls ./variants/fallback/libtrellis2.so  # old ABI
# after
git pull && make -C backend rebuild-trellis2 && rm ./variants/fallback/libtrellis2.so
Defensive patterns

Strategy: validation

Validate before calling

// before starting the server, verify the ABI matches
lib, err := purego.Dlopen(libName, purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil { log.Fatal(err) }
// bind t2AbiVersion and compare to your compiled-in abiVersion first

Prevention

When it happens

Trigger: Mixing a Go trellis2cpp binary built against one version of trellis2_capi.h with a libtrellis2.so built from another (e.g. after a partial upgrade, or picking up a stale ./variants/fallback/libtrellis2.so).

Common situations: Upgrading LocalAI core without rebuilding backends; CI caching the Go binary but rebuilding the C++ lib (or vice versa); a downstream packager shipping mismatched lib/binary pairs; switching between CUDA and fallback variants built at different revisions.

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/26c3769f5e41cf43. Report an issue: GitHub.