apache/hadoop · error
EINVAL
EINVAL
Error message
port %d was given, but URI '%s' already contains a port!
What it means
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.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-native-client/src/main/native/libhdfs/hdfs.c:658
*/
static int calcEffectiveURI(struct hdfsBuilder *bld, char ** uri)
{
const char *scheme;
char suffix[64];
const char *lastColon;
char *u;
size_t uriLen;
if (!bld->nn)
return EINVAL;
scheme = (strstr(bld->nn, "://")) ? "" : "hdfs://";
if (bld->port == 0) {
suffix[0] = '\0';
} else {
lastColon = strrchr(bld->nn, ':');
if (lastColon && (strspn(lastColon + 1, "0123456789") ==
strlen(lastColon + 1))) {
fprintf(stderr, "port %d was given, but URI '%s' already "
"contains a port!\n", bld->port, bld->nn);
return EINVAL;
}
snprintf(suffix, sizeof(suffix), ":%d", bld->port);
}
uriLen = strlen(scheme) + strlen(bld->nn) + strlen(suffix);
u = malloc((uriLen + 1) * (sizeof(char)));
if (!u) {
fprintf(stderr, "calcEffectiveURI: out of memory");
return ENOMEM;
}
snprintf(u, uriLen + 1, "%s%s%s", scheme, bld->nn, suffix);
*uri = u;
return 0;
}
static const char *maybeNull(const char *str)View on GitHub (pinned to 2add963021)
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.
Example fix
// before - port specified twice, returns NULL with errno EINVAL
hdfsFS fs = hdfsConnect("hdfs://namenode1:8020", 8020);
// after - port lives in exactly one place
hdfsFS fs = hdfsConnect("namenode1", 8020);
// or
hdfsFS fs = hdfsConnect("hdfs://namenode1:8020", 0); Defensive patterns
Strategy: validation
Validate before calling
static int nn_string_has_port(const char *nn) {
const char *c = strrchr(nn, ':');
return c && c[1] && strspn(c + 1, "0123456789") == strlen(c + 1);
}
/* configure the builder with the port in exactly ONE place */
struct hdfsBuilder *bld = hdfsNewBuilder();
if (nn_string_has_port(nn_uri)) {
hdfsBuilderSetNameNode(bld, nn_uri); /* port already inside URI */
} else {
hdfsBuilderSetNameNode(bld, nn_uri);
hdfsBuilderSetNameNodePort(bld, port); /* port supplied separately */
}
hdfsFS fs = hdfsBuilderConnect(bld); Type guard
static int hdfs_connect_args_valid(const char *nn, int port) {
/* mirrors calcEffectiveURI's check: reject port + URI-with-port */
if (port != 0) {
const char *c = strrchr(nn, ':');
if (c && c[1] && strspn(c + 1, "0123456789") == strlen(c + 1))
return 0;
}
return nn != NULL;
} Try / catch
hdfsFS fs = hdfsBuilderConnect(bld);
if (!fs) {
if (errno == EINVAL) {
/* double-port or missing nn: fix builder config, do not retry as-is */
} else {
/* connectivity / auth failure: check stderr for the JNI-level cause */
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/9dceff0d69d0c151.
Report an issue: GitHub.