apache/hadoop · error · UnsupportedOperationException
This feature is disabled. Please refer to dfs.client.block.
Error message
This feature is disabled. Please refer to dfs.client.block.write.replace-datanode-on-failure.enable configuration property.
What it means
Thrown by the HDFS client write pipeline when it needs to add a replacement datanode (a pipeline member was lost and the remaining replicas would fall below the minimum) but datanode replacement is switched off. dfs.client.block.write.replace-datanode-on-failure.enable=false maps to Policy.DISABLE, and checkEnabled() aborts the write instead of continuing with an under-replicated pipeline.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/ReplaceDatanodeOnFailure.java:107
private interface Condition {
/** Is the condition satisfied? */
boolean satisfy(short replication, DatanodeInfo[] existings, int nExistings,
boolean isAppend, boolean isHflushed);
}
private final Policy policy;
private final boolean bestEffort;
public ReplaceDatanodeOnFailure(Policy policy, boolean bestEffort) {
this.policy = policy;
this.bestEffort = bestEffort;
}
/** Check if the feature is enabled. */
public void checkEnabled() {
if (policy == Policy.DISABLE) {
throw new UnsupportedOperationException(
"This feature is disabled. Please refer to "
+ HdfsClientConfigKeys.BlockWrite.ReplaceDatanodeOnFailure.ENABLE_KEY
+ " configuration property.");
}
}
/**
* Best effort means that the client will try to replace the failed datanode
* (provided that the policy is satisfied), however, it will continue the
* write operation in case that the datanode replacement also fails.
*
* @return Suppose the datanode replacement fails.
* false: An exception should be thrown so that the write will fail.
* true : The write should be resumed with the remaining datandoes.
*/
public boolean isBestEffort() {
return bestEffort;
}View on GitHub (pinned to 2add963021)
Solutions
- Set dfs.client.block.write.replace-datanode-on-failure.enable=true (or remove the property) in the client's hdfs-client.xml/core-site.xml so a replacement datanode can be added
- On single-node clusters keep enable=false but set dfs.client.block.write.replace-datanode-on-failure.policy=NEVER so the replacement condition is never satisfied and checkEnabled() is never reached
- Ensure the cluster has spare datanodes so a replacement actually exists when the policy fires
- Retry the failed write after the config change; the setting is read from each client Configuration instance
Example fix
// before (hdfs-client.xml) <property> <name>dfs.client.block.write.replace-datanode-on-failure.enable</name> <value>false</value> </property> <property> <name>dfs.client.block.write.replace-datanode-on-failure.policy</name> <value>DEFAULT</value> </property> // after (single-node cluster) <property> <name>dfs.client.block.write.replace-datanode-on-failure.enable</name> <value>false</value> </property> <property> <name>dfs.client.block.write.replace-datanode-on-failure.policy</name> <value>NEVER</value> </property> // after (multi-node cluster) <property> <name>dfs.client.block.write.replace-datanode-on-failure.enable</name> <value>true</value> </property>
Defensive patterns
Strategy: validation
Validate before calling
Configuration conf = new Configuration();
try {
ReplaceDatanodeOnFailure.get(conf).checkEnabled();
} catch (UnsupportedOperationException e) {
throw new IllegalStateException(
"Writes will fail on datanode loss: set "
+ "dfs.client.block.write.replace-datanode-on-failure.enable=true "
+ "or policy=NEVER", e);
} Try / catch
catch (UnsupportedOperationException e) when thrown from DFSOutputStream.write/hflush/append: report the replace-datanode-on-failure config to the operator instead of retrying the write blindly.
Prevention
- On single-node clusters always pair enable=false with policy=NEVER
- Smoke-test a small write followed by a datanode kill in staging to catch disabled pipeline recovery
- Keep client hdfs-client.xml under config management so the flag is never silently disabled
When it happens
Trigger: During write/append/hflush a datanode in the pipeline dies, the policy condition is satisfied (e.g. DEFAULT condition: replication would drop below minReplication), and ReplaceDatanodeOnFailure.get(conf).checkEnabled() is invoked with policy == DISABLE because the enable property is false.
Common situations: Single-node or pseudo-distributed test clusters where the feature was disabled per old guidance ('set enable=false on small clusters') without also setting policy=NEVER; inherited production configs; appends after a datanode restart on tiny clusters.
Related errors
- Can not create a Path from a null string
- Can not create a Path from an empty string
- no SharedFileDescriptorFactory paths were configured.
- Failed to create ${basePath}[source=${source}, allow-append=
- Error connecting to file system: ${basePath} [${ex}]
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/15d59a5af6dab15d.
Report an issue: GitHub.