{"record":{"id":"fbf30ced4c7b8197","repo":"apache/hadoop","slug":"providedreplica-does-not-support-deleting-metadata","errorCode":null,"errorMessage":"ProvidedReplica does not support deleting metadata","messagePattern":"ProvidedReplica does not support deleting metadata","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ProvidedReplica.java","lineNumber":261,"sourceCode":"  public long getBlockDataLength() {\n    return this.getNumBytes();\n  }\n\n  @Override\n  public LengthInputStream getMetadataInputStream(long offset)\n      throws IOException {\n    return new LengthInputStream(new ByteArrayInputStream(NULL_CHECKSUM_ARRAY),\n        NULL_CHECKSUM_ARRAY.length);\n  }\n\n  @Override\n  public boolean metadataExists() {\n    return NULL_CHECKSUM_ARRAY == null ? false : true;\n  }\n\n  @Override\n  public boolean deleteMetadata() {\n    throw new UnsupportedOperationException(\n        \"ProvidedReplica does not support deleting metadata\");\n  }\n\n  @Override\n  public long getMetadataLength() {\n    return NULL_CHECKSUM_ARRAY == null ? 0 : NULL_CHECKSUM_ARRAY.length;\n  }\n\n  @Override\n  public boolean renameMeta(URI destURI) throws IOException {\n    throw new UnsupportedOperationException(\n        \"ProvidedReplica does not support renaming metadata\");\n  }\n\n  @Override\n  public boolean renameData(URI destURI) throws IOException {\n    throw new UnsupportedOperationException(\n        \"ProvidedReplica does not support renaming data\");","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ProvidedReplica.java#L243-L279","documentation":"ProvidedReplica (ProvidedReplica.java:53) is the ReplicaInfo implementation for HDFS provided storage (HDFS-9140): a DataNode serves block bytes from an external, read-only store referenced by URI/FileRegion instead of local disks. Its checksum 'metadata' is a synthesized NULL_CHECKSUM_ARRAY, not a real meta file. deleteMetadata() therefore unconditionally throws UnsupportedOperationException because the DataNode has no authority to delete anything in the external store.","triggerScenarios":"Calling ReplicaInfo.deleteMetadata() on a ProvidedReplica or FinalizedProvidedReplica instance. This happens when block-invalidation cleanup, directory-scanner reconciliation, or hand-written DataNode test/util code obtains a replica living on a PROVIDED volume (FsVolumeImpl replaced by ProvidedVolumeImpl) and tries to purge its .meta sidecar like a local replica.","commonSituations":"A cluster or test has a PROVIDED entry in dfs.datanode.data.dir (e.g. [ProvidedVolumeFactory]) with dfs.provided.alias-map configured, while code, cleanup tooling, or unit tests still assume every replica is a local-disk FinalizedReplica with deletable metadata.","solutions":["Guard the call: skip deleteMetadata() when replica instanceof ProvidedReplica (or volume is a ProvidedVolumeImpl); provided replicas are read-only references.","Keep deletion/invalidation logic scoped to local volumes only; never point block-deletion utilities at provided storage.","If you subclass ProvidedReplica with a genuinely writable backend, override deleteMetadata() to implement the delete.","As a last-resort boundary, catch UnsupportedOperationException and log-and-skip rather than crashing the cleanup loop."],"exampleFix":"// before\nreplica.deleteMetadata();\n\n// after\nif (!(replica instanceof ProvidedReplica)) {\n  replica.deleteMetadata();\n} else {\n  LOG.debug(\"Skipping metadata delete for PROVIDED replica {}\", replica.getBlockId());\n}","handlingStrategy":"validation","validationCode":"if (replica instanceof ProvidedReplica) {\n  LOG.debug(\"Skipping metadata delete for PROVIDED replica {}\", replica.getBlockId());\n} else {\n  replica.deleteMetadata();\n}","typeGuard":"static boolean isProvided(ReplicaInfo r) {\n  return r instanceof ProvidedReplica;\n}","tryCatchPattern":"try {\n  replica.deleteMetadata();\n} catch (UnsupportedOperationException e) {\n  LOG.warn(\"Replica {} is read-only provided storage: {}\",\n      replica.getBlockId(), e.getMessage());\n}","preventionTips":["Treat every PROVIDED volume as read-only; audit all mutating ReplicaInfo calls in your code path.","Filter provided replicas/volumes before deletion, rename, copy, and pinning operations.","Keep a type-check helper (instanceof ProvidedReplica) and use it consistently in generic block tooling."],"tags":["hdfs","datanode","provided-storage","read-only","metadata"],"backgroundTag":"unsupported-operation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}