{"record":{"id":"9dceff0d69d0c151","repo":"apache/hadoop","slug":"einval-9dceff","errorCode":"EINVAL","errorMessage":"port %d was given, but URI '%s' already contains a port!\n","messagePattern":"port (.+?) was given, but URI '(.+?)' already contains a port!\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/hdfs.c","lineNumber":658,"sourceCode":" */\nstatic int calcEffectiveURI(struct hdfsBuilder *bld, char ** uri)\n{\n    const char *scheme;\n    char suffix[64];\n    const char *lastColon;\n    char *u;\n    size_t uriLen;\n\n    if (!bld->nn)\n        return EINVAL;\n    scheme = (strstr(bld->nn, \"://\")) ? \"\" : \"hdfs://\";\n    if (bld->port == 0) {\n        suffix[0] = '\\0';\n    } else {\n        lastColon = strrchr(bld->nn, ':');\n        if (lastColon && (strspn(lastColon + 1, \"0123456789\") ==\n                          strlen(lastColon + 1))) {\n            fprintf(stderr, \"port %d was given, but URI '%s' already \"\n                \"contains a port!\\n\", bld->port, bld->nn);\n            return EINVAL;\n        }\n        snprintf(suffix, sizeof(suffix), \":%d\", bld->port);\n    }\n\n    uriLen = strlen(scheme) + strlen(bld->nn) + strlen(suffix);\n    u = malloc((uriLen + 1) * (sizeof(char)));\n    if (!u) {\n        fprintf(stderr, \"calcEffectiveURI: out of memory\");\n        return ENOMEM;\n    }\n    snprintf(u, uriLen + 1, \"%s%s%s\", scheme, bld->nn, suffix);\n    *uri = u;\n    return 0;\n}\n\nstatic const char *maybeNull(const char *str)","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/hdfs.c#L640-L676","documentation":"hdfsBuilderConnect assembles the effective NameNode URI in calcEffectiveURI: if the configured nn string already ends with ':<digits>' (textual check via strrchr + strspn) AND a non-zero port was also set via hdfsBuilderSetNameNodePort (or the port argument of hdfsConnect/hdfsConnectAsUser), the URI would carry two ports; libhdfs rejects this with EINVAL before any JVM work. hdfsBuilderConnect returns NULL with errno EINVAL.","triggerScenarios":"hdfsConnect(\"hdfs://nn:8020\", 8020); hdfsBuilderSetNameNode(bld, \"nn.example.com:8020\") followed by hdfsBuilderSetNameNodePort(bld, 8020); or any app/config that supplies both a URI-with-port and a separate port value to the same builder.","commonSituations":"Code migrated from host+port style (hdfsConnect(host, port)) to URI strings while the old port argument stayed; fuse-dfs or tools configured with both 'uri=hdfs://host:port' and a port key; copy-pasted connection helpers that always set a port.","solutions":["Encode the port exactly once: pass \"hdfs://nn:8020\" as nn and leave the port unset (0), or pass the bare host \"nn\" plus port 8020.","Search app code and config for both sources of the port (URI string and builder port setter) and remove one.","When hdfsBuilderConnect returns NULL, log bld->nn and bld->port together - the stderr message already echoes both, making the double-port obvious.","Distinguish this from connectivity failures by checking errno == EINVAL immediately after the failed connect."],"exampleFix":"// before - port specified twice, returns NULL with errno EINVAL\nhdfsFS fs = hdfsConnect(\"hdfs://namenode1:8020\", 8020);\n\n// after - port lives in exactly one place\nhdfsFS fs = hdfsConnect(\"namenode1\", 8020);\n// or\nhdfsFS fs = hdfsConnect(\"hdfs://namenode1:8020\", 0);","handlingStrategy":"validation","validationCode":"static int nn_string_has_port(const char *nn) {\n    const char *c = strrchr(nn, ':');\n    return c && c[1] && strspn(c + 1, \"0123456789\") == strlen(c + 1);\n}\n\n/* configure the builder with the port in exactly ONE place */\nstruct hdfsBuilder *bld = hdfsNewBuilder();\nif (nn_string_has_port(nn_uri)) {\n    hdfsBuilderSetNameNode(bld, nn_uri);            /* port already inside URI */\n} else {\n    hdfsBuilderSetNameNode(bld, nn_uri);\n    hdfsBuilderSetNameNodePort(bld, port);          /* port supplied separately */\n}\nhdfsFS fs = hdfsBuilderConnect(bld);","typeGuard":"static int hdfs_connect_args_valid(const char *nn, int port) {\n    /* mirrors calcEffectiveURI's check: reject port + URI-with-port */\n    if (port != 0) {\n        const char *c = strrchr(nn, ':');\n        if (c && c[1] && strspn(c + 1, \"0123456789\") == strlen(c + 1))\n            return 0;\n    }\n    return nn != NULL;\n}","tryCatchPattern":"hdfsFS fs = hdfsBuilderConnect(bld);\nif (!fs) {\n    if (errno == EINVAL) {\n        /* double-port or missing nn: fix builder config, do not retry as-is */\n    } else {\n        /* connectivity / auth failure: check stderr for the JNI-level cause */\n    }\n}","preventionTips":["Pick one convention (URI strings or host+port) per codebase and enforce it in a single connection helper.","Log bld->nn and the port together on connect failure to catch double-port configs immediately.","Remember hdfsBuilderConnect returns NULL for both config errors (EINVAL) and connectivity errors - always inspect errno.","In config files, document that the port key and an inline :port in the URI are mutually exclusive."],"tags":["c","libhdfs","uri","configuration","einval","connection"],"backgroundTag":"uri-port-conflict","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}