AvaloniaUI/Avalonia · error · DllNotFoundException
Unable to load {libraryPath} via dlopen
Error message
Unable to load {libraryPath} via dlopen What it means
After resolving libHarfBuzzSharp's directory via dlinfo(RTLD_DI_ORIGIN), the workaround dlopen()s the full path with RTLD_NOW|RTLD_DEEPBIND. A zero return means the loader could not open the file. The message string still literally contains '{libraryPath}' (not interpolated), so it is a second bug — the path is never printed.
Source
Thrown at samples/XEmbedSample/HarfbuzzWorkaround.cs:56
private const int RTLD_NOW = 2;
private const int RTLD_DEEPBIND = 8;
public static void Apply()
{
if (RuntimeInformation.RuntimeIdentifier.Contains("musl"))
throw new PlatformNotSupportedException("musl doesn't support RTLD_DEEPBIND");
var libraryPathBytes = Marshal.AllocHGlobal(4096);
var handle = NativeLibrary.Load("libHarfBuzzSharp", typeof(HarfBuzzSharp.Blob).Assembly, null);
dlinfo(handle, RTLD_DI_ORIGIN, libraryPathBytes);
var libraryOrigin = Marshal.PtrToStringUTF8(libraryPathBytes) ?? string.Empty;
Marshal.FreeHGlobal(libraryPathBytes);
var libraryPath = Path.Combine(libraryOrigin, "libHarfBuzzSharp.so");
NativeLibrary.Free(handle);
var forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);
if (forceLoadedHandle == IntPtr.Zero)
throw new DllNotFoundException($"Unable to load {libraryPath} via dlopen");
NativeLibrary.SetDllImportResolver(typeof(HarfBuzzSharp.Blob).Assembly, (name, assembly, searchPath) =>
{
if (name.Contains("HarfBuzzSharp"))
return dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);
return NativeLibrary.Load(name, assembly, searchPath);
});
}
}
View on GitHub (pinned to 11c5427268)
Solutions
- Verify libHarfBuzzSharp.so exists at the resolved libraryOrigin and is readable (note the message bug — print dlerror() instead).
- Ensure the published RID matches the runtime (linux-x64 vs linux-arm64 vs linux-musl-x64).
- Install missing system dependencies (fontconfig, libstdc++).
- Call dlerror() after a zero return and include its message for the real cause.
Example fix
// before
var forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);
if (forceLoadedHandle == IntPtr.Zero)
throw new DllNotFoundException($"Unable to load {libraryPath} via dlopen");
// after (interpolate the path AND surface dlerror)
var forceLoadedHandle = dlopen(libraryPath, RTLD_NOW | RTLD_DEEPBIND);
if (forceLoadedHandle == IntPtr.Zero)
{
var err = Marshal.PtrToStringAnsi(dlerror()) ?? "unknown";
throw new DllNotFoundException($"Unable to load '{libraryPath}' via dlopen: {err}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// confirm the native lib is present and loadable if (!File.Exists(libraryPath)) return; // missing binary for this RID
Type guard
static bool LibExists(string path) => File.Exists(path) && NativeLibrary.TryLoad(path, out _);
Try / catch
try { HarfbuzzWorkaround.Apply(); }
catch (DllNotFoundException ex)
{ _logger.LogError("HarfBuzz native load failed; ensure RID-matched lib exists. {Msg}", ex.Message); } Prevention
- Publish with the correct RID (linux-x64 vs linux-musl-x64 vs linux-arm64).
- Print dlerror() in the message to reveal the loader's reason.
- Install host deps: fontconfig, libstdc++.
When it happens
Trigger: dlopen returning IntPtr.Zero: the resolved library path does not exist, the file is the wrong architecture (e.g. x64 vs arm64), library is not readable (permissions), or a dependency is missing (libstdc++, libfontconfig). Happens when the RID-packaged native lib is absent from the expected directory.
Common situations: Publishing self-contained with the wrong RID; trimming removing the native HarfBuzzSharp binary; mismatched libHarfBuzzSharp.so ABI; missing system fonts/fontconfig on the host.
Related errors
- musl doesn't support RTLD_DEEPBIND
- Unable to export IOSurfaceRef
- Value must be less than 10.
- Transition elements have different parents.
- Give me 5 or more letter please :-)
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/4fec23fe2a8ef6b7.
Report an issue: GitHub.