{"record":{"id":"7fc00fc7ca9fd2f0","repo":"apache/hadoop","slug":"printexceptionandfree-error-determining-class-nam","errorCode":null,"errorMessage":"PrintExceptionAndFree: error determining class name of exception.\n","messagePattern":"PrintExceptionAndFree: error determining class name of exception\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/exception.c","lineNumber":160,"sourceCode":"        destroyLocalReference(env, jthr);\n        return NULL;\n    }\n    destroyLocalReference(env, jStr);\n    return excString;\n}\n\nint printExceptionAndFreeV(JNIEnv *env, jthrowable exc, int noPrintFlags,\n        const char *fmt, va_list ap)\n{\n    int i, noPrint, excErrno;\n    char *className = NULL;\n    jthrowable jthr;\n    const char *stackTrace;\n    const char *rootCause;\n\n    jthr = classNameOfObject(exc, env, &className);\n    if (jthr) {\n        fprintf(stderr, \"PrintExceptionAndFree: error determining class name \"\n            \"of exception.\\n\");\n        className = strdup(\"(unknown)\");\n        destroyLocalReference(env, jthr);\n    }\n    for (i = 0; i < EXCEPTION_INFO_LEN; i++) {\n        if (!strcmp(gExceptionInfo[i].name, className)) {\n            break;\n        }\n    }\n    if (i < EXCEPTION_INFO_LEN) {\n        noPrint = (gExceptionInfo[i].noPrintFlag & noPrintFlags);\n        excErrno = gExceptionInfo[i].excErrno;\n    } else {\n        noPrint = 0;\n        excErrno = EINTERNAL;\n    }\n\n    // We don't want to use ExceptionDescribe here, because that requires a","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/exception.c#L142-L178","documentation":"While converting a Java exception thrown by an internal JNI call into an errno, libhdfs first asks the JVM for the exception's class name (classNameOfObject). If that JNI lookup itself fails, this message is printed, the class name is replaced with \"(unknown)\", and processing continues; because \"(unknown)\" matches no entry in the gExceptionInfo table, the caller receives EINTERNAL. It usually indicates the JVM itself is in trouble (most often OutOfMemoryError) rather than a problem with the original HDFS operation.","triggerScenarios":"Any hdfs* call (hdfsOpenFile, hdfsRename, ...) whose JNI invocation throws, and while printExceptionAndFreeV processes the throwable, classNameOfObject also throws - e.g. the JVM cannot allocate the String for Class.getName(), or the JNIEnv is no longer healthy.","commonSituations":"JVM heap exhausted because LIBHDFS_OPTS/-Xmx is too small for the workload (large reads/writes, many threads); mismatched Hadoop jars causing class-resolution failures inside the JVM; long-running native processes with gradual JNI-reference or memory leaks.","solutions":["Check the adjacent stderr lines - the following '(unable to get root cause/stack trace)' lines and any JVM output usually identify the real failure.","Raise the libhdfs JVM heap: export LIBHDFS_OPTS=\"-Xmx2g\" (or HADOOP_OPTS) and retry the operation.","Verify CLASSPATH holds one consistent set of hadoop-common/hadoop-hdfs jars matching the libhdfs build.","Test the same operation via `hdfs dfs` with the same CLASSPATH to separate JVM-side breakage from cluster-side problems."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"int ret = hdfsRename(fs, from, to);   /* any hdfs* call */\nif (ret != 0) {\n    /* diagnostics may themselves fail; probe both channels */\n    const char *rc = hdfsGetLastExceptionRootCause();\n    const char *st = hdfsGetLastExceptionStackTrace();\n    log(\"hdfs failed errno=%d root=%s stack=%s\", errno,\n        rc ? rc : \"(unavailable)\", st ? st : \"(unavailable)\");\n    /* ret/EINTERNAL with NULL diagnostics => suspect JVM health, not HDFS */\n}","preventionTips":["Size the libhdfs JVM heap via LIBHDFS_OPTS=\"-Xmx...\" for worst-case workload, not average.","Ship libhdfs with the hadoop-common/hdfs jars from the same release on CLASSPATH.","Treat EINTERNAL returns with '(unknown)' class names as a JVM-health signal and capture stderr at that moment.","Monitor JVM memory of processes embedding libhdfs alongside native RSS."],"tags":["c","libhdfs","jni","jvm","exception-handling","einternal"],"backgroundTag":"jni-exception-diagnostics-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}