apache/hadoop · error
Environment variable CLASSPATH not set!
Error message
Environment variable CLASSPATH not set!
What it means
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.
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
Example fix
# before ./my_hdfs_app # Environment variable CLASSPATH not set! # after export CLASSPATH=$(hadoop classpath --glob) ./my_hdfs_app
Defensive patterns
Strategy: validation
Validate before calling
/* Fail fast before touching libhdfs */
if (getenv("CLASSPATH") == NULL) {
fprintf(stderr, "CLASSPATH unset; run: export CLASSPATH=$(hadoop classpath --glob)\n");
return EXIT_FAILURE;
} Try / catch
hdfsFS fs = hdfsConnect(nameNode, port);
if (fs == NULL) {
/* libhdfs printed the CLASSPATH line to stderr; errno is EINTERNAL */
fprintf(stderr, "hdfsConnect failed: errno=%d (%s)\n", errno, strerror(errno));
return EXIT_FAILURE;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Call to AttachCurrentThread failed with error
- Call to JNI_CreateJavaVM failed with error
- could not find method
- error: (no exception)
- JNI_GetCreatedJavaVMs failed with error
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/b6a34a1757e23bb0.
Report an issue: GitHub.
Appendix: source
Thrown at hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c:685
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);
// Determine the # of LIBHDFS_OPTS args
hadoopJvmArgs = getenv("LIBHDFS_OPTS");
if (hadoopJvmArgs != NULL) {
hadoopJvmArgs = strdup(hadoopJvmArgs);
for (noArgs = 1, str = hadoopJvmArgs; ; noArgs++, str = NULL) {
token = strtok_r(str, jvmArgDelims, &savePtr);
if (NULL == token) {
break;View on GitHub (pinned to 2add963021)