{"record":{"id":"6c897c5fd5551dba","repo":"apache/hadoop","slug":"trying-to-construct-a-provided-replica-on-witho","errorCode":null,"errorMessage":"Trying to construct a provided replica on {} without enough information","messagePattern":"Trying to construct a provided replica on (.+?) without enough information","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ReplicaBuilder.java","lineNumber":320,"sourceCode":"          + fromReplica.getBlockId());\n    }\n    if (fromReplica.getState() == ReplicaState.RUR) {\n      return new ReplicaUnderRecovery((ReplicaUnderRecovery) fromReplica);\n    } else {\n      return new ReplicaUnderRecovery(fromReplica, recoveryId);\n    }\n  }\n\n  private ProvidedReplica buildProvidedFinalizedReplica()\n      throws IllegalArgumentException {\n    ProvidedReplica info = null;\n    if (fromReplica != null) {\n      throw new IllegalArgumentException(\"Finalized PROVIDED replica \" +\n          \"cannot be constructed from another replica\");\n    }\n    if (fileRegion == null && uri == null &&\n        (pathPrefix == null || pathSuffix == null)) {\n      throw new IllegalArgumentException(\n          \"Trying to construct a provided replica on \" + volume +\n          \" without enough information\");\n    }\n    if (fileRegion == null) {\n      if (uri != null) {\n        info = new FinalizedProvidedReplica(blockId, uri, offset,\n            length, genStamp, pathHandle, volume, conf, remoteFS);\n      } else {\n        info = new FinalizedProvidedReplica(blockId, pathPrefix, pathSuffix,\n            offset, length, genStamp, pathHandle, volume, conf, remoteFS);\n      }\n    } else {\n      info = new FinalizedProvidedReplica(fileRegion, volume, conf, remoteFS);\n    }\n    return info;\n  }\n\n  private ProvidedReplica buildProvidedReplica()","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ReplicaBuilder.java#L302-L338","documentation":"ReplicaBuilder.buildProvidedFinalizedReplica() throws this IllegalArgumentException when a FINALIZED replica is being built on a PROVIDED storage volume but none of the three accepted data sources are set: a FileRegion, a remote URI, or a pathPrefix+pathSuffix pair. PROVIDED replicas do not store bytes locally; the builder needs at least one of these to describe where the data lives in the remote/external filesystem. This is a fail-fast guard so a meaningless ProvidedReplica is never constructed.","triggerScenarios":"Calling new ReplicaBuilder(ReplicaState.FINALIZED).setFsVolume(providedVolume)...build() where the volume's StorageType is PROVIDED, fromReplica is null, and none of setFileRegion(), setURI(), or both setPathPrefix(Path)+setPathSuffix(String) were called. build() routes to buildProvidedReplica() -> buildProvidedFinalizedReplica() and the fileRegion==null && uri==null && (pathPrefix==null || pathSuffix==null) guard fires.","commonSituations":"Writing a ProvidedStorageContext/FsDatasetSpi integration or unit tests for HDFS-9140 provided storage and forgetting to seed the builder with a FileRegion or URI; deserializing replicas from a PROVIDED volume's replica file where only the blockId/genStamp were parsed; setting pathPrefix without pathSuffix (or vice versa).","solutions":["Set a FileRegion on the builder if you have blockId+path+offset+length+genStamp: .setFileRegion(new FileRegion(...))","Otherwise set a remote-file URI plus offset/length: .setURI(uri).setOffset(..).setLength(..).setRemoteFS(remoteFS)","Otherwise set BOTH .setPathPrefix(prefixPath) and .setPathSuffix(suffix)","If you meant to copy an existing local replica, note fromReplica is explicitly rejected for PROVIDED FINALIZED - build from the FileRegion of the provided store instead"],"exampleFix":"// before\nReplicaInfo r = new ReplicaBuilder(ReplicaState.FINALIZED)\n    .setBlockId(bid).setGenerationStamp(gs).setLength(len)\n    .setFsVolume(providedVolume)   // no FileRegion/URI/path\n    .build();                      // IllegalArgumentException\n\n// after\nReplicaInfo r = new ReplicaBuilder(ReplicaState.FINALIZED)\n    .setBlockId(bid).setGenerationStamp(gs).setLength(len)\n    .setFsVolume(providedVolume)\n    .setFileRegion(new FileRegion(bp, bid, gs, remotePath, offset, len))\n    .setRemoteFS(remoteFS)\n    .build();","handlingStrategy":"validation","validationCode":"boolean canBuildProvidedFinalized(ReplicaBuilder b) {\n  return b.getFileRegion() != null\n      || b.getURI() != null\n      || (b.getPathPrefix() != null && b.getPathSuffix() != null);\n}\n// call before .build() when volume.getStorageType() == StorageType.PROVIDED","typeGuard":null,"tryCatchPattern":"try { replica = builder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"without enough information\")) { /* re-populate FileRegion/URI and rebuild */ } else throw e; }","preventionTips":["Always pair a PROVIDED FINALIZED build with exactly one of setFileRegion, setURI, or setPathPrefix+setPathSuffix","Centralize provided-replica construction in one factory method that always seeds a FileRegion"],"tags":["hdfs","datanode","provided-storage","replica","builder","illegal-argument"],"backgroundTag":"builder-missing-required-field","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}