{"record":{"id":"06022f9c8b0206c0","repo":"apache/hadoop","slug":"the-journal-edits-cache-is-not-enabled-which-is-a","errorCode":null,"errorMessage":"The journal edits cache is not enabled, which is a requirement to fetch journaled edits via RPC. Please enable it via dfs.ha.tail-edits.in-progress","messagePattern":"The journal edits cache is not enabled, which is a requirement to fetch journaled edits via RPC\\. Please enable it via dfs\\.ha\\.tail-edits\\.in-progress","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/Journal.java","lineNumber":749,"sourceCode":"          break;\n        }\n      }\n      if (log != null && log.isInProgress()) {\n        logs.add(new RemoteEditLog(log.getStartTxId(),\n            getHighestWrittenTxId(), true));\n      }\n    }\n\n    return new RemoteEditLogManifest(logs, getCommittedTxnId());\n  }\n\n  /**\n   * @see QJournalProtocol#getJournaledEdits(String, String, long, int)\n   */\n  public GetJournaledEditsResponseProto getJournaledEdits(long sinceTxId,\n      int maxTxns) throws IOException {\n    if (cache == null) {\n      throw new IOException(\"The journal edits cache is not enabled, which \" +\n          \"is a requirement to fetch journaled edits via RPC. Please enable \" +\n          \"it via \" + DFSConfigKeys.DFS_HA_TAILEDITS_INPROGRESS_KEY);\n    }\n    long highestTxId = getHighestWrittenTxId();\n    if (sinceTxId == highestTxId + 1) {\n      // Requested edits that don't exist yet, but this is expected,\n      // because namenode always get the journaled edits with the sinceTxId\n      // equal to image.getLastAppliedTxId() + 1. Short-circuiting the cache here\n      // and returning a response with a count of 0.\n      metrics.rpcEmptyResponses.incr();\n      return GetJournaledEditsResponseProto.newBuilder().setTxnCount(0).build();\n    } else if (sinceTxId > highestTxId + 1) {\n      // Requested edits that don't exist yet and this is unexpected. Means that there is a lag\n      // in this journal that does not contain some edits that should exist.\n      // Throw one NewerTxnIdException to make namenode treat this response as an exception.\n      // More detailed info please refer to: HDFS-16659 and HDFS-16771.\n      metrics.rpcEmptyResponses.incr();\n      throw new NewerTxnIdException(","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/Journal.java#L731-L767","documentation":"Journal.getJournaledEdits throws this IOException when a client (the NameNode tailing in-progress edits) calls the getJournaledEdits RPC but the JournalNode was not configured with the in-memory edits cache. The cache is enabled only by setting dfs.ha.tail-edits.in-progress=true, whose default is false (DFS_HA_TAILEDITS_INPROGRESS_DEFAULT). The cache is a hard prerequisite because journaled edits are served straight from memory, not by reading edit log files off disk.","triggerScenarios":"QJournalProtocol.getJournaledEdits(sinceTxId, maxTxns) is invoked while Journal.cache == null, i.e., the JournalNode started with dfs.ha.tail-edits.in-progress unset/false. Happens the moment a StandbyNameNode with tail-edits.in-progress enabled tries to tail from a JournalNode that lacks the setting.","commonSituations":"Enabling in-progress tailing on the NameNodes but forgetting the JournalNodes (the key must be set on JNs for the cache, and on NNs for the tailer); upgrading Hadoop and adopting the feature only on part of the HA ensemble; asymmetric hdfs-site.xml pushed by config management.","solutions":["Set dfs.ha.tail-edits.in-progress=true in hdfs-site.xml on every JournalNode and restart them so the edits cache is built.","Ensure the NameNodes that will tail also set dfs.ha.tail-edits.in-progress=true — mixed old/new nodes otherwise produce partial behavior.","If you do not want in-progress tailing, disable the feature on the tailing NameNode so it stops issuing getJournaledEdits RPCs.","After restart, verify with a jmx/log check that the JournalNode reports rpc txns served (metrics txnsServedViaRpc) instead of throwing."],"exampleFix":"<!-- before: JournalNode started with default -->\n<property>\n  <name>dfs.ha.tail-edits.in-progress</name>\n  <value>false</value>\n</property>\n<!-- IOException: The journal edits cache is not enabled ... -->\n\n<!-- after: enable the cache on ALL JournalNodes (and on the tailing NameNodes), then restart -->\n<property>\n  <name>dfs.ha.tail-edits.in-progress</name>\n  <value>true</value>\n</property>","handlingStrategy":"validation","validationCode":"boolean cacheEnabled = conf.getBoolean(\n    DFSConfigKeys.DFS_HA_TAILEDITS_INPROGRESS_KEY,\n    DFSConfigKeys.DFS_HA_TAILEDITS_INPROGRESS_DEFAULT); // default false\nif (!cacheEnabled) {\n  // skip getJournaledEdits; fall back to manifest+file tailing\n}","typeGuard":null,"tryCatchPattern":"try {\n  GetJournaledEditsResponseProto r = jn.getJournaledEdits(sinceTxId, maxTxns);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"journal edits cache is not enabled\")) {\n    // config gap on the JournalNode: report and disable in-progress tailing locally\n  } else { throw e; }\n}","preventionTips":["Set dfs.ha.tail-edits.in-progress=true on every JournalNode (and tailing NameNodes) before enabling the feature.","Deploy the same hdfs-site.xml aliasmap/HA keys to JNs and NNs via config management.","Smoke-test one getJournaledEdits RPC after enabling, before relying on it in production."],"tags":["hdfs","qjournal","configuration","ha","tail-edits","name-node"],"backgroundTag":"missing-configuration","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}