tursodatabase/turso · critical · InternalError

Unable to load necessary native library

Error message

Unable to load necessary native library

What it means

InternalError thrown from the lazy SingletonHolder static block when both loadFromSystemPath() and loadFromJar() fail, meaning the _turso_java native library was found neither on java.library.path nor inside the JAR for the detected OS/architecture. Because it fires in a static initializer, it surfaces as InternalError at whatever line first forces TursoDB class initialization (typically opening a database). Unlike the architecture throw, this one means the library files exist for the platform in principle but could not be located or extracted.

Solutions

  1. Verify the detected Architecture matches the host (see the separate ARM64-on-Linux throw)
  2. Place a working libturso_java.so on the library path: start the JVM with -Djava.library.path=/path/to/lib so loadFromSystemPath() succeeds
  3. Unzip the JAR and confirm it contains the native resource for your OS/arch; repair or re-pin the Maven/Gradle dependency if missing
  4. Ensure the extraction directory is writable and executable: -Djava.io.tmpdir pointing to an exec-mounted path
  5. Catch InternalError (and UnsatisfiedLinkError) at startup and fail fast, logging os.arch, java.library.path, and java.io.tmpdir

Example fix

// before
TursoDB db = TursoDB.open(path); // InternalError on first use

// after
try {
  TursoDB db = TursoDB.open(path);
} catch (InternalError | UnsatisfiedLinkError e) {
  throw new IllegalStateException("native load failed; os.arch="
      + System.getProperty("os.arch")
      + ", java.library.path=" + System.getProperty("java.library.path")
      + ", tmpdir=" + System.getProperty("java.io.tmpdir"), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean systemPathHasNative() {
  try {
    System.loadLibrary("_turso_java");
    return true;
  } catch (UnsatisfiedLinkError e) {
    return false;
  }
}
// call before first use: if false, verify the JAR carries natives for your os/arch
// and that java.io.tmpdir is writable+executable before letting TursoDB initialize

Try / catch

try {
  TursoDB db = TursoDB.open(path);
} catch (InternalError | UnsatisfiedLinkError e) {
  // note: InternalError is an Error, not an Exception — catch it explicitly
  throw new IllegalStateException(
      "native library load failed; os.arch=" + System.getProperty("os.arch")
          + ", java.library.path=" + System.getProperty("java.library.path")
          + ", tmpdir=" + System.getProperty("java.io.tmpdir"), e);
}

Prevention

When it happens

Trigger: java.library.path does not contain libturso_java.so and the JAR lacks a native resource matching Architecture.detect(); the temp directory used for extraction is read-only or mounted noexec; the JAR is corrupted or was shaded/repackaged in a way that dropped the embedded natives resource.

Common situations: Uber-jars and shadow-plugin builds stripping native resources; hardened containers with noexec TMPDIR; -Djava.library.path passed after JVM start or with a typo; a partial dependency download; running an x86_64-only artifact on an unsupported host.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/a43acc39366042e6. Report an issue: GitHub.

Appendix: source

Thrown at bindings/java/src/main/java/tech/turso/core/TursoDB.java:110

  /**
   * This method attempts to load the native library required for turso operations. It first tries
   * to load the library from the system's library path using {@link #loadFromSystemPath()}. If that
   * fails, it attempts to load the library from the JAR file using {@link #loadFromJar()}. If
   * either method succeeds, the `isLoaded` flag is set to true. If both methods fail, an {@link
   * InternalError} is thrown indicating that the necessary native library could not be loaded.
   *
   * @throws InternalError if the native library cannot be loaded from either the system path or the
   *     JAR file.
   */
  private static void load() {
    new SingletonHolder();
  }

  // "lazy initialization holder class idiom" (Effective Java #83)
  private static class SingletonHolder {
    static {
      if (!loadFromSystemPath() && !loadFromJar()) {
        throw new InternalError("Unable to load necessary native library");
      }
    }
  }

  /**
   * Load the native library from the system path.
   *
   * <p>This method attempts to load the native library named "_turso_java" from the system's
   * library path. If the library is successfully loaded, the `isLoaded` flag is set to true.
   *
   * @return true if the library was successfully loaded, false otherwise.
   */
  private static boolean loadFromSystemPath() {
    try {
      System.loadLibrary("_turso_java");
      return true;
    } catch (Throwable t) {
      logger.info("Unable to load from default path: {}", String.valueOf(t));

View on GitHub (pinned to 244cde92a7)