{"record":{"id":"dd03d04bd808d725","repo":"apache/hadoop","slug":"illegal-parameters-to-transferfsimage","errorCode":null,"errorMessage":"Illegal parameters to TransferFsImage","messagePattern":"Illegal parameters to TransferFsImage","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java","lineNumber":453,"sourceCode":"          }\n        } else if (key.equals(\"getedit\")) { \n          isGetEdit = true;\n          startTxId = ServletUtil.parseLongParam(request, START_TXID_PARAM);\n          endTxId = ServletUtil.parseLongParam(request, END_TXID_PARAM);\n        } else if (key.equals(STORAGEINFO_PARAM)) {\n          storageInfoString = val[0];\n        } else if (key.equals(\"getaliasmap\")) {\n          isGetAliasMap = true;\n          String bootstrapStandby = ServletUtil.getParameter(request,\n              IS_BOOTSTRAP_STANDBY);\n          isBootstrapStandby = bootstrapStandby != null &&\n              Boolean.parseBoolean(bootstrapStandby);\n        }\n      }\n\n      int numGets = (isGetImage?1:0) + (isGetEdit?1:0) + (isGetAliasMap?1:0);\n      if ((numGets > 1) || (numGets == 0)) {\n        throw new IOException(\"Illegal parameters to TransferFsImage\");\n      }\n    }\n\n    public String getStorageInfoString() {\n      return storageInfoString;\n    }\n\n    public long getTxId() {\n      Preconditions.checkState(isGetImage);\n      return txId;\n    }\n\n    public NameNodeFile getNameNodeFile() {\n      Preconditions.checkState(isGetImage);\n      return nnf;\n    }\n\n    public long getStartTxId() {","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java#L435-L471","documentation":"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.","triggerScenarios":"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.","commonSituations":"Custom monitoring or backup tooling hitting the servlet directly; version assumptions about the parameter contract; typo'd query keys; modified 2NN deployments.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Compose the query with exactly one operation before calling the servlet\nstatic URI buildTransferUrl(String host, int port, String op, long txid, String storageInfo) {\n  Set<String> allowed = new HashSet<>(Arrays.asList(\"getimage\", \"getedit\", \"getaliasmap\"));\n  if (!allowed.contains(op)) {\n    throw new IllegalArgumentException(\"op must be one of \" + allowed + \": \" + op);\n  }\n  return URI.create(String.format(\"http://%s:%d/imagetransfer?%s=1&txid=%d&storageInfo=%s\",\n      host, port, op, txid, storageInfo));\n}","typeGuard":"// narrows a raw query string to a valid single-op request\nstatic boolean isSingleOpRequest(String query) {\n  if (query == null) return false;\n  long n = 0;\n  for (String p : Arrays.asList(\"getimage\", \"getedit\", \"getaliasmap\")) {\n    if (query.matches(\"(^|&)(?i)\" + p + \"(=[^&]*)?($|&)\")) n++;\n  }\n  return n == 1;\n}","tryCatchPattern":"try {\n  getImage(params);\n} catch (IOException e) {\n  if (\"Illegal parameters to TransferFsImage\".equals(e.getMessage())) {\n    throw new IllegalArgumentException(\"Bad transfer query - exactly one of getimage/getedit/getaliasmap required\", e);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["hdfs","http","request-validation","query-params"],"backgroundTag":"invalid-request-parameters","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}