apache/pulsar · critical · MetadataStoreException

Failed to load RocksDB JNI library

Error message

Failed to load RocksDB JNI library

What it means

RocksdbMetadataStore's constructor first calls RocksDB.loadLibrary() to load the native RocksDB JNI library. If the native library cannot be loaded for this platform/architecture, instantiation fails immediately with this exception (wrapping the underlying Throwable).

Source

Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/impl/RocksdbMetadataStore.java:219

        return ByteBuffer.wrap(bytes).getLong();
    }

    private final String metadataUrl;

    /**
     * @param metadataURL         format "rocksdb:{storePath}"
     * @param metadataStoreConfig
     * @throws MetadataStoreException
     */
    private RocksdbMetadataStore(String metadataURL, MetadataStoreConfig metadataStoreConfig)
            throws MetadataStoreException {
        super(metadataStoreConfig.getMetadataStoreName(), metadataStoreConfig.getOpenTelemetry(),
                metadataStoreConfig.getNodeSizeStats(), metadataStoreConfig.getNumSerDesThreads());
        this.metadataUrl = metadataURL;
        try {
            RocksDB.loadLibrary();
        } catch (Throwable t) {
            throw new MetadataStoreException("Failed to load RocksDB JNI library", t);
        }

        String dataDir = metadataURL.substring("rocksdb:".length());
        Path dataPath = FileSystems.getDefault().getPath(dataDir);
        try {
            Files.createDirectories(dataPath);
            Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
            Files.setPosixFilePermissions(dataPath, perms);
        } catch (IOException e) {
            throw new MetadataStoreException("Fail to create RocksDB file directory", e);
        }

        db = openDB(dataPath.toString(), metadataStoreConfig.getConfigFilePath());

        this.writeOptions = new WriteOptions().setSync(metadataStoreConfig.isFsyncEnable());
        this.optionCache = new ReadOptions().setFillCache(true);
        this.optionDontCache = new ReadOptions().setFillCache(false);

View on GitHub (pinned to 820761864e)

Solutions

  1. Verify the rocksdbjni dependency jar is on the classpath and matches your OS/arch; re-add the correct artifact.
  2. Check that java.io.tmpdir is writable and executable (noexec mounts break JNI temp extraction).
  3. Install required native libraries (libstdc++, glibc) or run on a supported glibc-based platform.
  4. Set TMPDIR to an exec-permitted directory or preload the native lib; confirm with `System.loadLibrary` in a smoke test.
Defensive patterns

Strategy: validation

Validate before calling

// fail fast at startup, before creating the store
try (var in = getClass().getResourceAsStream("/librocksdbjni.so")) {
    if (in == null) throw new IllegalStateException("rocksdbjni native artifact missing from classpath");
}
RocksDB.loadLibrary(); // smoke test

Try / catch

try {
    MetadataStore s = MetadataStoreFactory.create("rocksdb:/data/meta");
} catch (MetadataStoreException e) {
    if (e.getMessage().contains("JNI library")) {
        log.error("RocksDB native lib unavailable on this platform/arch", e);
        // fall back to another metadata store implementation
    } else throw e;
}

Prevention

When it happens

Trigger: Creating a RocksdbMetadataStore via the metadata store factory with URL scheme rocksdb:// on a JVM where the rocksdbjni native library is missing, unsupported, or blocked.

Common situations: Running on an unsupported architecture (e.g. ARM/alpine musl) without a matching rocksdbjni artifact; missing OS shared-library dependencies (glibc, libstdc++); temp dir mounted noexec so JNI extraction fails; stripped classpath missing the rocksdbjni jar.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/6cc22b97805101c5. Report an issue: GitHub.