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
- Verify the library exists and is a valid ELF/Mach-O of the right architecture (file libparakeet.so)
- Build the native parakeet library and place it where the backend runs, or set PARAKEET_LIBRARY to its absolute path
- Resolve missing dependencies shown by ldd libparakeet.so / otool -L libparakeet.dylib
- 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
- Rebuild both Go backend and native lib together on upgrades
- Preserve the variants/ directory layout when packaging
- Stat the library in a prestart hook so failures are actionable
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
- ced: dlopen %q: %w
- face-detect: dlopen %q: %w
- moss-transcribe-cpp: dlopen %q: %w
- voice-detect: dlopen %q: %w
- trellis2 ABI mismatch: library reports %d, backend built for
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/f76ec1b6a4ef49b5.
Report an issue: GitHub.