{"record":{"id":"9515e0e268d9ff54","repo":"apache/hadoop","slug":"expected-classpath-expansion-length-to-be-zu-but","errorCode":null,"errorMessage":"Expected classpath expansion length to be %zu but instead got %zu\n","messagePattern":"Expected classpath expansion length to be %zu but instead got %zu\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":629,"sourceCode":"    }\n\n    // Allocte memory for expanded classpath string\n    expandedClasspath = calloc(length, sizeof(char));\n    if (expandedClasspath == NULL) {\n        fprintf(stderr, \"getClassPath: failed calloc: %s\\n\", strerror(errno));\n        return NULL;\n    }\n\n    // Actual expansion\n    retval = getClassPath_helper(classpath, expandedClasspath);\n    if (retval < 0) {\n        free(expandedClasspath);\n        return NULL;\n    }\n\n    // This should not happen, but dotting i's and crossing t's\n    if (retval != length) {\n        fprintf(stderr,\n          \"Expected classpath expansion length to be %zu but instead got %zu\\n\",\n          length, retval);\n        free(expandedClasspath);\n        return NULL;\n    }\n\n#ifdef _LIBHDFS_JNI_HELPER_DEBUGGING_ON_\n    printf(\"===============\\n\");\n    printf(\"Allocated %zd for expanding classpath\\n\", length);\n    printf(\"Used %zu for expanding classpath\\n\", strlen(expandedClasspath) + 1);\n    printf(\"Expanded classpath=%s\\n\", expandedClasspath);\n#endif\n\n    return expandedClasspath;\n}\n\n\n/**","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/jni_helper.c#L611-L647","documentation":"getClassPath expands wildcards in two passes: one getClassPath_helper call sizes the buffer, a second fills it. If the length returned by the second pass differs from the first, this invariant message is printed, the buffer is freed, and setup fails. The usual cause is the directory contents changing between the two passes, since the sizing pass ran earlier.","triggerScenarios":"Jars added or removed in a wildcard directory between the sizing and filling passes; concurrent deployments writing into the same install tree while a client initializes.","commonSituations":"Automated upgrade jobs writing into share/hadoop/* while processes start; shared mounts used simultaneously by many clients.","solutions":["Retry the operation: with a stable directory the two passes agree","Point wildcard classpath entries at versioned, immutable directories","Pre-expand the CLASSPATH (hadoop classpath --glob) to skip the two-pass logic entirely"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"/* transient: directory changed between sizing and fill passes */\nfor (int attempt = 0; attempt < 3; attempt++) {\n    hdfsFS fs = hdfsConnect(uri, user);\n    if (fs) break;\n    if (errno != EINTERNAL) break;          /* only retry JVM-bootstrap failures */\n    /* brief backoff; with a stable directory the two passes agree */\n    usleep(200 * 1000);\n}","preventionTips":["Point wildcard classpath entries at immutable, versioned directories","Pre-expand CLASSPATH with `hadoop classpath --glob` to skip the two-pass expansion","Avoid upgrading jars in place while clients start"],"tags":["hdfs","libhdfs","classpath","race-condition","wildcard-expansion"],"backgroundTag":"classpath-expansion-failure","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}