apache/hadoop · error · IOException
Illegal parameters to TransferFsImage
Error message
Illegal parameters to TransferFsImage
What it means
GetImageParams, the GET-side parameter parser of ImageServlet, requires that exactly one transfer operation is selected: the counters isGetImage, isGetEdit and isGetAliasMap must total exactly one. Requesting two things at once (numGets > 1) or none at all (numGets == 0) is rejected as an illegal TransferFsImage request before any data is served.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java:453
}
} else if (key.equals("getedit")) {
isGetEdit = true;
startTxId = ServletUtil.parseLongParam(request, START_TXID_PARAM);
endTxId = ServletUtil.parseLongParam(request, END_TXID_PARAM);
} else if (key.equals(STORAGEINFO_PARAM)) {
storageInfoString = val[0];
} else if (key.equals("getaliasmap")) {
isGetAliasMap = true;
String bootstrapStandby = ServletUtil.getParameter(request,
IS_BOOTSTRAP_STANDBY);
isBootstrapStandby = bootstrapStandby != null &&
Boolean.parseBoolean(bootstrapStandby);
}
}
int numGets = (isGetImage?1:0) + (isGetEdit?1:0) + (isGetAliasMap?1:0);
if ((numGets > 1) || (numGets == 0)) {
throw new IOException("Illegal parameters to TransferFsImage");
}
}
public String getStorageInfoString() {
return storageInfoString;
}
public long getTxId() {
Preconditions.checkState(isGetImage);
return txId;
}
public NameNodeFile getNameNodeFile() {
Preconditions.checkState(isGetImage);
return nnf;
}
public long getStartTxId() {View on GitHub (pinned to 2add963021)
Solutions
- Send exactly one lowercase operation parameter: getimage, getedit or getaliasmap, plus the required txid/storageinfo parameters.
- Instead of hand-building the URL, reuse the URL construction in TransferFsImage (it composes the exact parameter set the servlet expects).
- If a genuine Secondary or Standby produced the request, check for Hadoop version mixing between the NN and the peer.
Defensive patterns
Strategy: validation
Validate before calling
// Compose the query with exactly one operation before calling the servlet
static URI buildTransferUrl(String host, int port, String op, long txid, String storageInfo) {
Set<String> allowed = new HashSet<>(Arrays.asList("getimage", "getedit", "getaliasmap"));
if (!allowed.contains(op)) {
throw new IllegalArgumentException("op must be one of " + allowed + ": " + op);
}
return URI.create(String.format("http://%s:%d/imagetransfer?%s=1&txid=%d&storageInfo=%s",
host, port, op, txid, storageInfo));
} Type guard
// narrows a raw query string to a valid single-op request
static boolean isSingleOpRequest(String query) {
if (query == null) return false;
long n = 0;
for (String p : Arrays.asList("getimage", "getedit", "getaliasmap")) {
if (query.matches("(^|&)(?i)" + p + "(=[^&]*)?($|&)")) n++;
}
return n == 1;
} Try / catch
try {
getImage(params);
} catch (IOException e) {
if ("Illegal parameters to TransferFsImage".equals(e.getMessage())) {
throw new IllegalArgumentException("Bad transfer query - exactly one of getimage/getedit/getaliasmap required", e);
}
throw e;
} Prevention
- Never hand-write imagetransfer URLs; reuse TransferFsImage client builders.
- Parameter names are lowercase and case-sensitive - getimage, getedit, getaliasmap.
- Add a unit assertion on your URL builder that exactly one op key is present.
When it happens
Trigger: GET /imagetransfer with both getimage=1 and getedit=1, with neither operation parameter, or with misspelled parameter names (getImage vs getimage) - typically from hand-written scripts or curl rather than the real Secondary, whose client code always sends exactly one op.
Common situations: Custom monitoring or backup tooling hitting the servlet directly; version assumptions about the parameter contract; typo'd query keys; modified 2NN deployments.
Related errors
- Unrecognized value '{}' for dfs.http.policy
- Image transfer servlet at " + url + " failed with status cod
- Fetch of url failed with status code connection.getResponseC
- "Invalid Content-Length header: " + contentLength
- "Content-Length header is not provided by the server when tr
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/dd03d04bd808d725.
Report an issue: GitHub.