apache/hadoop · critical
JNI_GetCreatedJavaVMs failed with error: %d
Error message
JNI_GetCreatedJavaVMs failed with error: %d
What it means
The first step of JVM bootstrap in getGlobalJNIEnv is JNI_GetCreatedJavaVMs to check whether a VM already exists in the process. A non-zero return code (JNI_ERR, or a version-incompatibility error from the detected VM) prints this message and makes getJNIEnv return NULL, after which every libhdfs call fails with EINTERNAL.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c:677
JNIEnv *env;
jint rv = 0;
jint noVMs = 0;
jthrowable jthr;
char *hadoopClassPath;
const char *hadoopClassPathVMArg = "-Djava.class.path=";
size_t optHadoopClassPathLen;
char *optHadoopClassPath;
int noArgs = 1;
char *hadoopJvmArgs;
char jvmArgDelims[] = " ";
char *str, *token, *savePtr;
JavaVMInitArgs vm_args;
JavaVM *vm;
JavaVMOption *options;
rv = JNI_GetCreatedJavaVMs(&(vmBuf[0]), VM_BUF_LENGTH, &noVMs);
if (rv != 0) {
fprintf(stderr, "JNI_GetCreatedJavaVMs failed with error: %d\n", rv);
return NULL;
}
if (noVMs == 0) {
//Get the environment variables for initializing the JVM
hadoopClassPath = getClassPath();
if (hadoopClassPath == NULL) {
fprintf(stderr, "Environment variable CLASSPATH not set!\n");
return NULL;
}
optHadoopClassPathLen = strlen(hadoopClassPath) +
strlen(hadoopClassPathVMArg) + 1;
optHadoopClassPath = malloc(sizeof(char)*optHadoopClassPathLen);
snprintf(optHadoopClassPath, optHadoopClassPathLen,
"%s%s", hadoopClassPathVMArg, hadoopClassPath);
free(hadoopClassPath);
View on GitHub (pinned to 2add963021)
Solutions
- Verify JAVA_HOME/LD_LIBRARY_PATH point at a complete JDK matching the process architecture and version
- Identify which JVM an embedding framework already created in-process and align its version with Hadoop's expectation
- Validate the JDK with a trivial JNI program against the same environment to isolate libhdfs
Example fix
# before export LD_LIBRARY_PATH=/opt/partial-jdk/lib/server:/opt/hadoop/lib/native # broken JDK copy # after export JAVA_HOME=/usr/lib/jvm/java-8-openjdk export LD_LIBRARY_PATH=$JAVA_HOME/lib/server:/opt/hadoop/lib/native
Defensive patterns
Strategy: validation
Validate before calling
/* validate the JVM environment before the first libhdfs call */
static int jvm_env_ok(void) {
const char *jh = getenv("JAVA_HOME");
char path[PATH_MAX];
if (!jh) return 0;
snprintf(path, sizeof(path), "%s/lib/server/libjvm.so", jh);
return access(path, R_OK) == 0; /* complete, matching-arch JDK required */
} Try / catch
if (hdfsConnect(uri, user) == NULL && errno == EINTERNAL) {
/* check stderr for 'JNI_GetCreatedJavaVMs failed': fix JAVA_HOME/LD_LIBRARY_PATH,
do not retry with the same broken environment */
} Prevention
- Pin JAVA_HOME and LD_LIBRARY_PATH to one complete JDK in service env scripts
- Align the JDK version/architecture of embedding frameworks with the Hadoop installation
- Validate the JDK with a trivial JNI program when in doubt
When it happens
Trigger: A broken or architecture-mismatched libjvm.so on LD_LIBRARY_PATH; an existing JVM of an incompatible version already created in the process by an embedding framework; a corrupted JDK installation.
Common situations: Mixed Java versions between an embedding application and the Hadoop installation; LD_LIBRARY_PATH pointing at a partial JDK copy; 32-bit vs 64-bit library mismatch.
Related errors
- PrintExceptionAndFree: error determining class name of excep
- error: (no exception)
- EIO
- EINTERNAL
- could not find method %s from class %s with signature %s
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/28075496153cc3c4.
Report an issue: GitHub.