{"record":{"id":"799c6b9f6ea8f56f","repo":"apache/hadoop","slug":"wrong-fs-expected","errorCode":null,"errorMessage":"Wrong FS {} -expected {}","messagePattern":"Wrong FS (.+?) -expected (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSLoginHelper.java","lineNumber":257,"sourceCode":"        URI defaultUri = FileSystem.getDefaultUri(conf);\n        if (equalsIgnoreCase(thisScheme, defaultUri.getScheme())) {\n          pathUri\n              = defaultUri; // schemes match, so use this uri instead\n        } else {\n          pathUri = null; // can't determine auth of the path\n        }\n      }\n      if (pathUri != null) {\n        // canonicalize uri before comparing with this fs\n        pathUri = canonicalizeUri(pathUri, defaultPort);\n        thatHost = pathUri.getHost();\n        if (equalsIgnoreCase(thisHost, thatHost)) {\n          return;\n        }\n      }\n    }\n    // make sure the exception strips out any auth details\n    throw new IllegalArgumentException(\n        \"Wrong FS \" + OBSLoginHelper.toString(pathUri) + \" -expected \"\n            + fsUri);\n  }\n\n  /**\n   * Simple tuple of login details.\n   */\n  public static class Login {\n    /**\n     * Defined empty login instance.\n     */\n    public static final Login EMPTY = new Login();\n\n    /**\n     * Defined user name.\n     */\n    private final String user;\n","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSLoginHelper.java#L239-L275","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use fully-qualified paths that match the filesystem instance: obs://<bucket>/key for an OBSFileSystem mounted on <bucket>","Keep fs.defaultFS and fs.obs.bucket.name consistent with the bucket named in every path","Obtain the filesystem from the path itself: FileSystem fs = path.getFileSystem(conf), so scheme and authority always agree","Qualify relative paths against the target filesystem with path.makeQualified(fsUri, workingDir) before use","For cross-filesystem transfers run distcp with explicit source and destination URIs instead of one filesystem instance"],"exampleFix":"// before\nFileSystem fs = FileSystem.get(conf);            // bound to obs://my-bucket\nfs.open(new Path(\"obs://other-bucket/data/x\"));    // Wrong FS obs://other-bucket/data/x -expected obs://my-bucket\n\n// after\nFileSystem fs = new Path(\"obs://other-bucket/\").getFileSystem(conf);\nfs.open(new Path(\"obs://other-bucket/data/x\"));","handlingStrategy":"validation","validationCode":"// before any fs operation on `path`\nURI fsUri = fs.getUri();\nURI pUri = path.toUri();\nboolean schemeOk = pUri.getScheme() == null || pUri.getScheme().equals(fsUri.getScheme());\nboolean hostOk = pUri.getHost() == null || pUri.getHost().equals(fsUri.getHost());\nif (!schemeOk || !hostOk) {\n  throw new IllegalArgumentException(\"Path \" + path + \" does not belong to \" + fsUri);\n}","typeGuard":"static boolean belongsTo(FileSystem fs, Path p) {\n  URI u = p.toUri();\n  URI f = fs.getUri();\n  return (u.getScheme() == null || u.getScheme().equals(f.getScheme()))\n      && (u.getHost() == null || u.getHost().equals(f.getHost()));\n}","tryCatchPattern":"try {\n  fs.open(path);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Wrong FS\")) {\n    FileSystem actual = path.getFileSystem(conf); // resolve the right filesystem\n    // retry on `actual` or fail with a clear message\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always build the filesystem from the path: path.getFileSystem(conf)","Keep fs.defaultFS, fs.obs.bucket.name, and the bucket in every path identical","Store fully-qualified URIs in job input/output configuration","Never embed credentials in the URI authority; they change the host comparison"],"tags":["hadoop","obs","path-validation","uri-authority","configuration"],"backgroundTag":"wrong-filesystem-uri","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}