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.
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)
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
- PrintExceptionAndFree: error determining class name of excep
- (unable to get root cause for %s)
- (unable to get stack trace for %s)
- error: (no exception)
- 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/b6a34a1757e23bb0.
Report an issue: GitHub.