mudler/LocalAI · critical

parakeet-cpp: dlopen %q: %w

Error message

parakeet-cpp: dlopen %q: %w

What it means

Startup panic of the Go parakeet-cpp backend when purego.Dlopen fails to load the Parakeet transcription library. Name comes from PARAKEET_LIBRARY, defaulting to libparakeet.dylib (macOS) or libparakeet.so (Linux); RTLD_NOW forces immediate symbol resolution so undefined parakeet_capi_* symbols also produce this error.

Source

Thrown at backend/go/parakeet-cpp/main.go:42

type LibFuncs struct {
	FuncPtr any
	Name    string
}

func main() {
	libName := os.Getenv("PARAKEET_LIBRARY")
	if libName == "" {
		if runtime.GOOS == "darwin" {
			libName = "libparakeet.dylib"
		} else {
			libName = "libparakeet.so"
		}
	}

	lib, err := purego.Dlopen(libName, purego.RTLD_NOW|purego.RTLD_GLOBAL)
	if err != nil {
		panic(fmt.Errorf("parakeet-cpp: dlopen %q: %w", libName, err))
	}

	// Bound 1:1 to parakeet_capi.h. The C-API returns malloc'd char*
	// buffers from transcribe_*; we register those as uintptr so we get
	// the raw pointer back and can call parakeet_capi_free_string on it
	// (purego's string return would copy and forget the original pointer,
	// leaking it on every call).
	libFuncs := []LibFuncs{
		{&CppAbiVersion, "parakeet_capi_abi_version"},
		{&CppLoad, "parakeet_capi_load"},
		{&CppFree, "parakeet_capi_free"},
		{&CppTranscribePath, "parakeet_capi_transcribe_path"},
		{&CppTranscribePathJSON, "parakeet_capi_transcribe_path_json"},
		{&CppStreamBegin, "parakeet_capi_stream_begin"},
		{&CppStreamFeed, "parakeet_capi_stream_feed"},
		{&CppStreamFinalize, "parakeet_capi_stream_finalize"},
		{&CppStreamFree, "parakeet_capi_stream_free"},
		{&CppFreeString, "parakeet_capi_free_string"},

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Verify the library exists and is a valid ELF/Mach-O of the right architecture (file libparakeet.so)
  2. Build the native parakeet library and place it where the backend runs, or set PARAKEET_LIBRARY to its absolute path
  3. Resolve missing dependencies shown by ldd libparakeet.so / otool -L libparakeet.dylib
  4. If using the fallback variant path, make sure the variants/fallback directory layout is intact

Example fix

# before
./parakeet-cpp  # panic: parakeet-cpp: dlopen "libparakeet.so": ...
# after
PARAKEET_LIBRARY=/opt/localai/backends/libparakeet.so ./parakeet-cpp
Defensive patterns

Strategy: validation

Validate before calling

lib := os.Getenv("PARAKEET_LIBRARY"); if lib == "" { lib = defaultLibName() }
if _, err := os.Stat(lib); err != nil { log.Fatalf("parakeet-cpp: library %q missing: %v", lib, err) }

Type guard

func libAvailable(path string) bool { _, err := os.Stat(path); return err == nil }

Prevention

When it happens

Trigger: Backend started before the C++ library is built/installed; PARAKEET_LIBRARY set to a non-library or truncated file; the .so cannot find its own runtime dependencies; architecture mismatch between the Go process and the library.

Common situations: Fresh deployments that ship the Go binary but not the artifacts/ directory containing the .so; upgrading the Go backend without rebuilding the native lib (ABI drift often shows as dlopen failure when soname deps change); containers missing CUDA/ONNX runtime libs.

Related errors


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