risingwavelabs/risingwave · critical
not root
Error message
not root
What it means
locate_libs_path derives the JVM `libs` directory relative to the current executable path. After canonicalizing the executable path it calls .parent().expect("not root"), so the process panics with `not root` if the executable sits directly in the filesystem root directory — its path has no parent component. This is an internal invariant that should never hold in a normal installation.
Solutions
- Move the binary into a subdirectory (e.g. /opt/risingwave/risingwave) so its path has a parent.
- Alternatively set CONNECTOR_LIBS_PATH explicitly to skip executable-relative resolution.
- Restore the standard installation layout (binary next to a `libs` directory).
- Keep binary and `libs` folder siblings in any custom packaging.
Example fix
// before COPY risingwave /risingwave // after COPY risingwave /opt/risingwave/risingwave && COPY libs /opt/risingwave/libs
Defensive patterns
Strategy: validation
Validate before calling
import os, sys
exe = os.path.realpath(sys.argv[0])
parent = os.path.dirname(exe)
assert parent not in ('/', ''), 'binary must not live at filesystem root; move it or set CONNECTOR_LIBS_PATH' Prevention
- Install the binary in a dedicated directory (e.g. /opt/risingwave/) with `libs` alongside it.
- Set CONNECTOR_LIBS_PATH explicitly in deployment scripts and container images.
- Add a preflight check in your launch script that the exe path has a parent directory.
When it happens
Trigger: Running the RisingWave binary from the filesystem root (e.g. copied to /risingwave or /) so std::env::current_exe().parent() returns None, triggering the expect panic during build_jvm_with_native_registration.
Common situations: Container images that place the binary at /, custom deployments relocating the binary, docker ENTRYPOINT copying the binary to root instead of /usr/local/bin.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- invalid entry_path obtained from fs::read_dir
- All valid CDC connectors should have returned by now
- AZBLOB_ENDPOINT not found from environment variables
- BatchPosixFsReader should not hit this branch. refer to…
- below watermark check condition eval must return bool array
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/01440ab3f30367dd.
Report an issue: GitHub.
Appendix: source
Thrown at src/jni_core/src/jvm_runtime.rs:45
use crate::opendal_schema_history::*;
use crate::{call_method, call_static_method};
/// Use 10% of compute total memory by default. Compute node uses 0.7 * system memory by default.
const DEFAULT_MEMORY_PROPORTION: f64 = 0.07;
fn locate_libs_path() -> anyhow::Result<PathBuf> {
let libs_path = if let Ok(libs_path) = std::env::var("CONNECTOR_LIBS_PATH") {
PathBuf::from(libs_path)
} else {
tracing::info!(
"environment variable CONNECTOR_LIBS_PATH is not specified, use default path `./libs` instead"
);
std::env::current_exe()
.and_then(|p| p.fs_err_canonicalize()) // resolve symlink of the current executable
.context("unable to get path of the executable")?
.parent()
.expect("not root")
.join("libs")
};
Ok(libs_path)
}
fn build_jvm_with_native_registration() -> anyhow::Result<JavaVM> {
let libs_path = locate_libs_path().context("failed to locate connector libs")?;
tracing::info!(path = %libs_path.display(), "located connector libs");
let mut class_vec = vec![];
let entries = fs::read_dir(&libs_path).context(if cfg!(debug_assertions) {
"failed to read connector libs; \
for RiseDev users, please check if ENABLE_BUILD_RW_CONNECTOR is set with `risedev configure`"
} else {
"failed to read connector libs, \
please check if env var CONNECTOR_LIBS_PATH is correctly configured"
})?;View on GitHub (pinned to 6469eb736d)