mudler/LocalAI · critical
moss-transcribe-cpp: dlopen %q: %w
Error message
moss-transcribe-cpp: dlopen %q: %w
What it means
Startup panic of the Go moss-transcribe-cpp backend when purego.Dlopen cannot load the Moss transcription library. Name comes from MOSS_TRANSCRIBE_LIBRARY, defaulting to libmoss-transcribe.dylib (macOS) or libmoss-transcribe.so (Linux). Loaded with RTLD_NOW so unresolved symbols also surface here as a dlopen error.
Source
Thrown at backend/go/moss-transcribe-cpp/main.go:42
type LibFuncs struct {
FuncPtr any
Name string
}
func main() {
libName := os.Getenv("MOSS_TRANSCRIBE_LIBRARY")
if libName == "" {
if runtime.GOOS == "darwin" {
libName = "libmoss-transcribe.dylib"
} else {
libName = "libmoss-transcribe.so"
}
}
lib, err := purego.Dlopen(libName, purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(fmt.Errorf("moss-transcribe-cpp: dlopen %q: %w", libName, err))
}
// Bound 1:1 to moss_transcribe_capi.h. The transcribe_* entry points return
// a malloc'd char* the caller owns; we register those as uintptr so we get
// the raw pointer back and can call moss_transcribe_capi_free_string on it
// (purego's string return would copy and forget the original pointer,
// leaking it on every call).
libFuncs := []LibFuncs{
{&CppAbiVersion, "moss_transcribe_capi_abi_version"},
{&CppLoad, "moss_transcribe_capi_load"},
{&CppFree, "moss_transcribe_capi_free"},
{&CppTranscribePath, "moss_transcribe_capi_transcribe_path"},
{&CppTranscribePcm, "moss_transcribe_capi_transcribe_pcm"},
{&CppFreeString, "moss_transcribe_capi_free_string"},
{&CppLastError, "moss_transcribe_capi_last_error"},
}
for _, lf := range libFuncs {
purego.RegisterLibFunc(lf.FuncPtr, lib, lf.Name)View on GitHub (pinned to 44413a9d06)
Solutions
- Confirm the library file exists at the resolved path (check MOSS_TRANSCRIBE_LIBRARY and the platform default name)
- Rebuild libmoss-transcribe from the backend's build recipe on the target host
- Point MOSS_TRANSCRIBE_LIBRARY at the absolute path of the freshly built library
- Use ldd/otool -L to find and install missing transitive dependencies
Example fix
# before ./moss-transcribe-cpp # panic: moss-transcribe-cpp: dlopen "libmoss-transcribe.so": ... # after MOSS_TRANSCRIBE_LIBRARY=/opt/localai/backends/libmoss-transcribe.so ./moss-transcribe-cpp
Defensive patterns
Strategy: validation
Validate before calling
lib := os.Getenv("MOSS_TRANSCRIBE_LIBRARY"); if lib == "" { lib = defaultLibName() }
if _, err := os.Stat(lib); err != nil { log.Fatalf("moss-transcribe-cpp: library %q missing: %v", lib, err) } Type guard
func libAvailable(path string) bool { _, err := os.Stat(path); return err == nil } Prevention
- Keep MOSS_TRANSCRIBE_LIBRARY absolute and stable across restarts
- Build the native lib on the target OS/arch
- Check transitive deps with ldd during image build
When it happens
Trigger: Starting moss-transcribe-cpp with the native lib missing from the loader path, MOSS_TRANSCRIBE_LIBRARY pointing at a stale or wrong-architecture build, or the .so's own dependencies (whisper/ffmpeg etc.) unavailable at runtime.
Common situations: Skipping the C++ build step; running on a host with older glibc than the build machine; mixed arm64/amd64 binaries copied between machines; env var set in a wrapper script that is not propagated to the service unit.
Related errors
- ced: dlopen %q: %w
- face-detect: dlopen %q: %w
- parakeet-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/6f962b691f4374d7.
Report an issue: GitHub.