{"record":{"id":"a0908ca57a6005c0","repo":"apache/hadoop","slug":"wrong-fs-pathuri-expected-fsuri","errorCode":null,"errorMessage":"Wrong FS {pathUri} -expected {fsUri}","messagePattern":"Wrong FS (.+?) -expected (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3native/S3xLoginHelper.java","lineNumber":149,"sourceCode":"        if (equalsIgnoreCase(thisScheme, defaultUri.getScheme())) {\n          pathUri = 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 (thisHost == thatHost ||       // hosts match\n            (thisHost != null &&\n                 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 \" + pathUri + \" -expected \" + fsUri);\n  }\n\n  /**\n   * Simple tuple of login details.\n   */\n  public static class Login {\n    private final String user;\n    private final String password;\n\n    /**\n     * Create an instance with no login details.\n     * Calls to {@link #hasLogin()} return false.\n     */\n    public Login() {\n      this(\"\", \"\");\n    }\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3native/S3xLoginHelper.java#L131-L167","documentation":"S3xLoginHelper.checkPath implements FileSystem.checkPath for the S3 filesystems: relative paths are accepted; otherwise the path scheme is compared (case-insensitively) with the filesystem's scheme, and when schemes match the hosts are compared after canonicalizing ports and patching a host-less path from fs.defaultFS. Any mismatch ends in IllegalArgumentException 'Wrong FS <pathUri> -expected <fsUri>', with any user:password auth details deliberately stripped from the message. This is the S3A form of Hadoop's classic 'Wrong FS' error.","triggerScenarios":"Obtaining one S3AFileSystem (e.g. FileSystem.get(new URI(\"s3a://bucket-a\"), conf)) and calling an operation with a fully-qualified path of a different bucket or scheme, such as fs.open(new Path(\"s3a://bucket-b/file\")); passing an hdfs:// path to an S3A instance; a path whose host cannot be patched because fs.defaultFS has a different scheme.","commonSituations":"Cached FileSystem instances reused across buckets in Spark/Hive/MapReduce jobs; hardcoded absolute URIs from another environment; mixed s3a:// and s3n:// or wasb:// references in one job; wrong fs.defaultFS in the configuration.","solutions":["Derive the filesystem from the path itself: FileSystem fs = path.getFileSystem(conf) - never reuse an instance bound to another bucket","Qualify paths against the filesystem you will use: path = path.makeQualified(fs.getUri(), new Path(\"/\"))","Route operations by scheme+host and keep one FileSystem instance per bucket","Do not embed secrets in URIs - the exception strips them from the message, but the underlying config should not contain them"],"exampleFix":"// before\nFileSystem fs = FileSystem.get(new URI(\"s3a://bucket-a\"), conf);\nfs.open(new Path(\"s3a://bucket-b/file\")); // Wrong FS\n// after\nPath p = new Path(\"s3a://bucket-b/file\");\nFileSystem fs = p.getFileSystem(conf); // instance bound to bucket-b\nfs.open(p);","handlingStrategy":"validation","validationCode":"static boolean pathMatchesFs(Configuration conf, URI fsUri, Path path, int defaultPort) {\n  URI p = path.toUri();\n  if (p.getScheme() == null) return true;\n  URI canonFs = S3xLoginHelper.canonicalizeUri(fsUri, defaultPort);\n  return p.getScheme().equalsIgnoreCase(canonFs.getScheme())\n      && (p.getHost() == null || p.getHost().equalsIgnoreCase(canonFs.getHost()));\n}\n// use: if (!pathMatchesFs(conf, fs.getUri(), p, -1)) { fs = p.getFileSystem(conf); }","typeGuard":null,"tryCatchPattern":"try {\n  fs.open(p);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Wrong FS\")) {\n    fs = p.getFileSystem(conf); // right filesystem for this path\n    fs.open(p);\n  } else { throw e; }\n}","preventionTips":["Always obtain the filesystem from the path: path.getFileSystem(conf)","Qualify paths with makeQualified before cross-component hand-off","Keep one FileSystem instance per bucket; never share an instance across buckets"],"tags":["s3a","uri","checkpath","filesystem","illegal-argument"],"backgroundTag":"wrong-filesystem-uri","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}