apache/hadoop · error · IllegalArgumentException

Wrong FS {} -expected {}

Error message

Wrong FS {} -expected {}

What it means

Thrown by OBSLoginHelper.checkPath, which OBSFileSystem invokes to validate every Path it receives. The path URI is canonicalized and its host is compared with the authority of the filesystem URI; on mismatch it throws IllegalArgumentException('Wrong FS <path> -expected <fsUri>') with auth details stripped from the message. This is the standard Hadoop FileSystem.checkPath contract: a Path must belong to the filesystem instance that receives it.

Source

Thrown at hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSLoginHelper.java:257

        URI defaultUri = FileSystem.getDefaultUri(conf);
        if (equalsIgnoreCase(thisScheme, defaultUri.getScheme())) {
          pathUri
              = defaultUri; // schemes match, so use this uri instead
        } else {
          pathUri = null; // can't determine auth of the path
        }
      }
      if (pathUri != null) {
        // canonicalize uri before comparing with this fs
        pathUri = canonicalizeUri(pathUri, defaultPort);
        thatHost = pathUri.getHost();
        if (equalsIgnoreCase(thisHost, thatHost)) {
          return;
        }
      }
    }
    // make sure the exception strips out any auth details
    throw new IllegalArgumentException(
        "Wrong FS " + OBSLoginHelper.toString(pathUri) + " -expected "
            + fsUri);
  }

  /**
   * Simple tuple of login details.
   */
  public static class Login {
    /**
     * Defined empty login instance.
     */
    public static final Login EMPTY = new Login();

    /**
     * Defined user name.
     */
    private final String user;

View on GitHub (pinned to 2add963021)

Solutions

  1. Use fully-qualified paths that match the filesystem instance: obs://<bucket>/key for an OBSFileSystem mounted on <bucket>
  2. Keep fs.defaultFS and fs.obs.bucket.name consistent with the bucket named in every path
  3. Obtain the filesystem from the path itself: FileSystem fs = path.getFileSystem(conf), so scheme and authority always agree
  4. Qualify relative paths against the target filesystem with path.makeQualified(fsUri, workingDir) before use
  5. For cross-filesystem transfers run distcp with explicit source and destination URIs instead of one filesystem instance

Example fix

// before
FileSystem fs = FileSystem.get(conf);            // bound to obs://my-bucket
fs.open(new Path("obs://other-bucket/data/x"));    // Wrong FS obs://other-bucket/data/x -expected obs://my-bucket

// after
FileSystem fs = new Path("obs://other-bucket/").getFileSystem(conf);
fs.open(new Path("obs://other-bucket/data/x"));
Defensive patterns

Strategy: validation

Validate before calling

// before any fs operation on `path`
URI fsUri = fs.getUri();
URI pUri = path.toUri();
boolean schemeOk = pUri.getScheme() == null || pUri.getScheme().equals(fsUri.getScheme());
boolean hostOk = pUri.getHost() == null || pUri.getHost().equals(fsUri.getHost());
if (!schemeOk || !hostOk) {
  throw new IllegalArgumentException("Path " + path + " does not belong to " + fsUri);
}

Type guard

static boolean belongsTo(FileSystem fs, Path p) {
  URI u = p.toUri();
  URI f = fs.getUri();
  return (u.getScheme() == null || u.getScheme().equals(f.getScheme()))
      && (u.getHost() == null || u.getHost().equals(f.getHost()));
}

Try / catch

try {
  fs.open(path);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Wrong FS")) {
    FileSystem actual = path.getFileSystem(conf); // resolve the right filesystem
    // retry on `actual` or fail with a clear message
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: An OBSFileSystem created for one bucket (via fs.obs.bucket.name or fs.defaultFS=obs://bucket/) receives a Path whose authority differs: obs://other-bucket/dir/file, hdfs://nn/..., file:///..., or an unqualified Path resolved against a different default FS. Also triggered by URIs carrying embedded userinfo (user:pass@host), which changes the authority being compared.

Common situations: fs.defaultFS points at HDFS while job inputs are obs:// URLs (or the reverse); bucket in the path differs from fs.obs.bucket.name; distcp between OBS and HDFS with partially-qualified paths; config files copied from another cluster; MapReduce/Spark driver resolving paths against the job FS instead of the path's own FS.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/799c6b9f6ea8f56f. Report an issue: GitHub.