apache/hadoop · error
Call to AttachCurrentThread failed with error: %d
Error message
Call to AttachCurrentThread failed with error: %d
What it means
A thread calling into libhdfs found an already-created JVM (JNI_GetCreatedJavaVMs returned one, so this is the second or later thread) and AttachCurrentThread failed with a non-zero JNI code (typically JNI_EVERSION or native-resource failure). getGlobalJNIEnv returns NULL, so this thread's HDFS call fails while other, already-attached threads keep working.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c:763
"with error: %d\n", rv);
return NULL;
}
// We use findClassAndInvokeMethod here because the jclasses in
// jclasses.h have not loaded yet
jthr = findClassAndInvokeMethod(env, NULL, STATIC, NULL, HADOOP_FS,
"loadFileSystems", "()V");
if (jthr) {
printExceptionAndFree(env, jthr, PRINT_EXC_ALL,
"FileSystem: loadFileSystems failed");
return NULL;
}
} else {
//Attach this thread to the VM
vm = vmBuf[0];
rv = (*vm)->AttachCurrentThread(vm, (void*)&env, 0);
if (rv != 0) {
fprintf(stderr, "Call to AttachCurrentThread "
"failed with error: %d\n", rv);
return NULL;
}
}
return env;
}
/**
* getJNIEnv: A helper function to get the JNIEnv* for the given thread.
* If no JVM exists, then one will be created. JVM command line arguments
* are obtained from the LIBHDFS_OPTS environment variable.
*
* Implementation note: we rely on POSIX thread-local storage (tls).
* This allows us to associate a destructor function with each thread, that
* will detach the thread from the Java VM when the thread terminates. If we
* failt to do this, it will cause a memory leak.
*View on GitHub (pinned to 2add963021)
Solutions
- Warm up each worker thread at startup with a cheap call (hdfsExists on "/") so attachment happens before real work and fails visibly
- For code -3 (JNI_EVERSION), align the runtime libjvm with the JVM libhdfs was built against
- For other codes, reduce concurrent thread count or raise memory limits so the JVM can allocate thread structures
- Make sure no thread issues HDFS calls while the process is tearing the JVM down
Example fix
// before: first libhdfs touch deep inside worker
void* worker(void *arg) {
hdfsRead(fs, file, buf, n); /* attach fails mid-job */
}
// after: force attach at thread start, fail fast
void* worker(void *arg) {
if (!fs_attached_ok()) return NULL; /* calls any hdfs API to trigger getJNIEnv */
hdfsRead(fs, file, buf, n);
} Defensive patterns
Strategy: fallback
Validate before calling
/* Warm up each worker: force attach at thread start, not mid-job */
static void warm_thread(hdfsFS fs) {
hdfsExists(fs, "/"); /* any call routes through getJNIEnv */
} Try / catch
if (someHdfsCall(fs) == -1 && errno == EINTERNAL) {
/* attach failed for this thread; route work to an attached worker */
enqueue_to_io_thread(op); /* fallback: single dedicated I/O thread */
} Prevention
- Warm up every worker thread with a cheap HDFS call before real work
- Prefer one dedicated I/O thread over ad-hoc threads calling libhdfs
- Stop threads before initiating JVM teardown at shutdown
When it happens
Trigger: Multi-threaded programs where a worker's first libhdfs call happens after another thread created the VM and the attach fails: JNI version negotiation problems after a JVM change, JVM unable to allocate per-thread native structures under memory pressure, or calls racing JVM destruction at shutdown.
Common situations: Thread pools creating threads late under heavy load; applications embedding libhdfs alongside another JVM owner; shutdown paths where a lingering thread calls an HDFS API while DestroyJavaVM is running.
Related errors
- PrintExceptionAndFree: error determining class name of excep
- error: (no exception)
- JNI_GetCreatedJavaVMs failed with error: %d
- Environment variable CLASSPATH not set!
- Call to JNI_CreateJavaVM failed with error: %d
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/7dcb5da0ad9e747f.
Report an issue: GitHub.