{"record":{"id":"a43acc39366042e6","repo":"tursodatabase/turso","slug":"unable-to-load-necessary-native-library","errorCode":null,"errorMessage":"Unable to load necessary native library","messagePattern":"Unable to load necessary native library","errorType":"exception","errorClass":"InternalError","httpStatus":null,"severity":"critical","filePath":"bindings/java/src/main/java/tech/turso/core/TursoDB.java","lineNumber":110,"sourceCode":"  /**\n   * This method attempts to load the native library required for turso operations. It first tries\n   * to load the library from the system's library path using {@link #loadFromSystemPath()}. If that\n   * fails, it attempts to load the library from the JAR file using {@link #loadFromJar()}. If\n   * either method succeeds, the `isLoaded` flag is set to true. If both methods fail, an {@link\n   * InternalError} is thrown indicating that the necessary native library could not be loaded.\n   *\n   * @throws InternalError if the native library cannot be loaded from either the system path or the\n   *     JAR file.\n   */\n  private static void load() {\n    new SingletonHolder();\n  }\n\n  // \"lazy initialization holder class idiom\" (Effective Java #83)\n  private static class SingletonHolder {\n    static {\n      if (!loadFromSystemPath() && !loadFromJar()) {\n        throw new InternalError(\"Unable to load necessary native library\");\n      }\n    }\n  }\n\n  /**\n   * Load the native library from the system path.\n   *\n   * <p>This method attempts to load the native library named \"_turso_java\" from the system's\n   * library path. If the library is successfully loaded, the `isLoaded` flag is set to true.\n   *\n   * @return true if the library was successfully loaded, false otherwise.\n   */\n  private static boolean loadFromSystemPath() {\n    try {\n      System.loadLibrary(\"_turso_java\");\n      return true;\n    } catch (Throwable t) {\n      logger.info(\"Unable to load from default path: {}\", String.valueOf(t));","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/java/src/main/java/tech/turso/core/TursoDB.java#L92-L128","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the detected Architecture matches the host (see the separate ARM64-on-Linux throw)","Place a working libturso_java.so on the library path: start the JVM with -Djava.library.path=/path/to/lib so loadFromSystemPath() succeeds","Unzip the JAR and confirm it contains the native resource for your OS/arch; repair or re-pin the Maven/Gradle dependency if missing","Ensure the extraction directory is writable and executable: -Djava.io.tmpdir pointing to an exec-mounted path","Catch InternalError (and UnsatisfiedLinkError) at startup and fail fast, logging os.arch, java.library.path, and java.io.tmpdir"],"exampleFix":"// before\nTursoDB db = TursoDB.open(path); // InternalError on first use\n\n// after\ntry {\n  TursoDB db = TursoDB.open(path);\n} catch (InternalError | UnsatisfiedLinkError e) {\n  throw new IllegalStateException(\"native load failed; os.arch=\"\n      + System.getProperty(\"os.arch\")\n      + \", java.library.path=\" + System.getProperty(\"java.library.path\")\n      + \", tmpdir=\" + System.getProperty(\"java.io.tmpdir\"), e);\n}","handlingStrategy":"try-catch","validationCode":"static boolean systemPathHasNative() {\n  try {\n    System.loadLibrary(\"_turso_java\");\n    return true;\n  } catch (UnsatisfiedLinkError e) {\n    return false;\n  }\n}\n// call before first use: if false, verify the JAR carries natives for your os/arch\n// and that java.io.tmpdir is writable+executable before letting TursoDB initialize","typeGuard":null,"tryCatchPattern":"try {\n  TursoDB db = TursoDB.open(path);\n} catch (InternalError | UnsatisfiedLinkError e) {\n  // note: InternalError is an Error, not an Exception — catch it explicitly\n  throw new IllegalStateException(\n      \"native library load failed; os.arch=\" + System.getProperty(\"os.arch\")\n          + \", java.library.path=\" + System.getProperty(\"java.library.path\")\n          + \", tmpdir=\" + System.getProperty(\"java.io.tmpdir\"), e);\n}","preventionTips":["Force TursoDB class initialization once inside a guarded startup block, never lazily on the first query","Keep the container temp directory writable and exec-mounted","Verify shaded/uber-jars keep the embedded native resources after repackaging","Log os.arch, java.library.path, and java.io.tmpdir in startup diagnostics"],"tags":["java","native-library","jni","classloader","internal-error"],"backgroundTag":"native-library-load-failure","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}