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

  1. Verify JAVA_HOME/LD_LIBRARY_PATH point at a complete JDK matching the process architecture and version
  2. Identify which JVM an embedding framework already created in-process and align its version with Hadoop's expectation
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/28075496153cc3c4. Report an issue: GitHub.