{"record":{"id":"b6a34a1757e23bb0","repo":"apache/hadoop","slug":"environment-variable-classpath-not-set","errorCode":null,"errorMessage":"Environment variable CLASSPATH not set!\n","messagePattern":"Environment variable CLASSPATH not set!\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c","lineNumber":685,"sourceCode":"    int noArgs = 1;\n    char *hadoopJvmArgs;\n    char jvmArgDelims[] = \" \";\n    char *str, *token, *savePtr;\n    JavaVMInitArgs vm_args;\n    JavaVM *vm;\n    JavaVMOption *options;\n\n    rv = JNI_GetCreatedJavaVMs(&(vmBuf[0]), VM_BUF_LENGTH, &noVMs);\n    if (rv != 0) {\n        fprintf(stderr, \"JNI_GetCreatedJavaVMs failed with error: %d\\n\", rv);\n        return NULL;\n    }\n\n    if (noVMs == 0) {\n        //Get the environment variables for initializing the JVM\n        hadoopClassPath = getClassPath();\n        if (hadoopClassPath == NULL) {\n            fprintf(stderr, \"Environment variable CLASSPATH not set!\\n\");\n            return NULL;\n        } \n        optHadoopClassPathLen = strlen(hadoopClassPath) + \n          strlen(hadoopClassPathVMArg) + 1;\n        optHadoopClassPath = malloc(sizeof(char)*optHadoopClassPathLen);\n        snprintf(optHadoopClassPath, optHadoopClassPathLen,\n                \"%s%s\", hadoopClassPathVMArg, hadoopClassPath);\n\n        free(hadoopClassPath);\n\n        // Determine the # of LIBHDFS_OPTS args\n        hadoopJvmArgs = getenv(\"LIBHDFS_OPTS\");\n        if (hadoopJvmArgs != NULL)  {\n          hadoopJvmArgs = strdup(hadoopJvmArgs);\n          for (noArgs = 1, str = hadoopJvmArgs; ; noArgs++, str = NULL) {\n            token = strtok_r(str, jvmArgDelims, &savePtr);\n            if (NULL == token) {\n              break;","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c#L667-L703","documentation":"libhdfs embeds a JVM inside your process. On the first HDFS call, when JNI_GetCreatedJavaVMs reports no existing VM, libhdfs builds the JVM's -Djava.class.path from the CLASSPATH environment variable (getClassPath() at jni_helper.c:574 is a plain getenv and returns NULL when unset). This message means that lookup failed, so getGlobalJNIEnv() aborts JVM creation and the triggering call (hdfsConnect/hdfsBuilderConnect or any API routed through getJNIEnv) returns NULL. Every subsequent call on this process fails the same way until CLASSPATH is present in the process environment.","triggerScenarios":"First libhdfs API call in a process where no JVM was previously created and getenv(\"CLASSPATH\") returns NULL: daemons, containers, cron jobs, or forked children that never inherited the variable from the parent shell.","commonSituations":"Running libhdfs apps or tests without sourcing the Hadoop environment; launching from systemd (no shell profile), Docker, or Kubernetes where the export never ran; sudo with env_reset stripping the variable; C services that link libhdfs but know nothing of the Hadoop scripts.","solutions":["Export CLASSPATH with the Hadoop jars and configs before starting the process: export CLASSPATH=$(hadoop classpath --glob)","If the process is started by systemd/docker, put the variable in that unit (Environment= line, Dockerfile ENV) so the exact PID sees it","Alternatively inject the classpath via LIBHDFS_OPTS=\"-Djava.class.path=<jars>\" which the JVM options carry even without the env var","Verify with /proc/<pid>/environ (or a trivial getenv test) that the running process actually has CLASSPATH; getenv only sees the process environment"],"exampleFix":"# before\n./my_hdfs_app\n# Environment variable CLASSPATH not set!\n\n# after\nexport CLASSPATH=$(hadoop classpath --glob)\n./my_hdfs_app","handlingStrategy":"validation","validationCode":"/* Fail fast before touching libhdfs */\nif (getenv(\"CLASSPATH\") == NULL) {\n    fprintf(stderr, \"CLASSPATH unset; run: export CLASSPATH=$(hadoop classpath --glob)\\n\");\n    return EXIT_FAILURE;\n}","typeGuard":null,"tryCatchPattern":"hdfsFS fs = hdfsConnect(nameNode, port);\nif (fs == NULL) {\n    /* libhdfs printed the CLASSPATH line to stderr; errno is EINTERNAL */\n    fprintf(stderr, \"hdfsConnect failed: errno=%d (%s)\\n\", errno, strerror(errno));\n    return EXIT_FAILURE;\n}","preventionTips":["Set CLASSPATH via `hadoop classpath --glob` in the same script/unit that starts the process","For systemd/docker launches, verify with /proc/<pid>/environ that the variable reached the process","Pin the classpath generation in a wrapper script so app and Hadoop version stay in sync"],"tags":["libhdfs","jni","classpath","environment-variable","jvm"],"backgroundTag":"missing-env-var","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}