github/copilot-sdk · critical · IllegalStateException

Failed to load native library from ''

Error message

Failed to load native library from ''

What it means

JnaNativeBinding's constructor loads the native runtime via Native.load(); an UnsatisfiedLinkError (missing symbols, wrong architecture, corrupt or dependency-lacking library) is converted to IllegalStateException including the absolute path attempted.

Solutions

  1. Delete the cached runtime file so it is re-extracted from a pristine source.
  2. Verify the binary architecture matches the JVM (file/libext on the .so/.dylib).
  3. Run ldd/otool on the library to find missing native dependencies and install them.
  4. Confirm the JDK bitness/OS matches the runtime artifact; update the loader/SDK.

Example fix

// before
Files.move(downloaded, cachePath); // may be truncated
// after
if (checksum(downloaded) != expectedChecksum) throw new IOException("corrupt runtime");
Files.move(downloaded, cachePath, StandardCopyOption.ATOMIC_MOVE);
Defensive patterns

Strategy: fallback

Validate before calling

if (!Files.isReadable(libPath)) throw new IOException("native lib unreadable");
Process p = new ProcessBuilder("file", libPath.toString()).inheritIO().start(); p.waitFor();

Try / catch

try { binding = new JnaNativeBinding(libPath); } catch (IllegalStateException ex) { purgeCache(); binding = new JnaNativeBinding(reextract(libPath)); }

Prevention

When it happens

Trigger: Native.load(absPath) fails: the extracted runtime file is corrupt/truncated, built for a different OS/arch, or missing transitive native dependencies (e.g. missing libc++/openssl).

Common situations: Downloading/extracting the runtime over a bad network leaving a truncated file; copying a linux-x64 binary to an arm64 machine; missing system libraries in a slim Docker image.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/abc3069605ca9cc0. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java:202

    /**
     * Loads (or re-uses) the native library at the given absolute path.
     *
     * @param libraryPath
     *            absolute path to the {@code runtime.node} native library
     * @throws IllegalStateException
     *             if a <em>different</em> library path has already been loaded in
     *             this JVM process
     */
    JnaNativeBinding(Path libraryPath) {
        Path absPath = libraryPath.toAbsolutePath().normalize();
        synchronized (LOAD_LOCK) {
            if (loadedLib == null) {
                LOG.fine(() -> "Loading native library from: " + absPath);
                try {
                    loadedLib = Native.load(absPath.toString(), CopilotRuntimeLibrary.class);
                } catch (UnsatisfiedLinkError e) {
                    throw new IllegalStateException("Failed to load native library from '" + absPath + "'", e);
                }
                loadedPath = absPath;
                LOG.fine(() -> "Native library loaded: " + absPath);
            } else if (!absPath.equals(loadedPath)) {
                throw new IllegalStateException("An in-process FFI runtime library is already loaded from '"
                        + loadedPath + "'; loading a different library from '" + absPath
                        + "' in the same process is not supported.");
            }
        }
        this.lib = loadedLib;
    }

    /**
     * Testing constructor — accepts a pre-built {@link CopilotRuntimeLibrary}
     * directly, bypassing disk I/O and the static singleton guard.
     *
     * <p>
     * This constructor is package-private and intended solely for unit tests.

View on GitHub (pinned to cd8cf15dc3)