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

  1. 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.
  2. Search app code and config for both sources of the port (URI string and builder port setter) and remove one.
  3. When hdfsBuilderConnect returns NULL, log bld->nn and bld->port together - the stderr message already echoes both, making the double-port obvious.
  4. 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

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.