apache/hadoop · error · IOException

Unable to refresh queues because queue-hierarchy changed…

Error message

Unable to refresh queues because queue-hierarchy changed. Retaining existing configuration. 

What it means

QueueManager.refreshQueues() (the target of 'mr admin -refresh-queues') only supports changing queue properties such as ACLs, state, and scheduler settings. It first checks root.isHierarchySameAs(): the new mapred-queues.xml must describe exactly the same queue names in the same parent-child structure. If any queue was added, removed, or renamed, this IOException is thrown and the previously loaded configuration stays active.

Solutions

  1. Restore the queue names and hierarchy to match the running configuration (only ACL/state/scheduler property values may differ), then run refresh again.
  2. To genuinely add or remove queues, plan a JobTracker restart instead of a refresh.
  3. Diff the new mapred-queues.xml against the last-known-good copy tree-by-tree before deploying it.
  4. Confirm all nodes see the same file so refreshes from different hosts agree.
Defensive patterns

Strategy: validation

Validate before calling

// before refresh: compare queue name trees of running config vs new file
Set<String> running = queueNamesAsPaths(qm.getQueueInfo().getChildren()); // e.g. "root.eng.etl"
QueueConfigurationParser cp = QueueConfigurationParser.parse("mapred-queues.xml.new");
Set<String> candidate = queueNamesAsPaths(cp.getRoot().getJobQueueInfo().getChildren());
if (!running.equals(candidate)) {
  throw new IOException("Hierarchy differs: only property updates allowed; added="
      + Sets.difference(candidate, running) + " removed=" + Sets.difference(running, candidate));
}

Try / catch

try {
  queueManager.refreshQueues(conf);
} catch (IOException e) {
  if (e.getMessage().contains("queue-hierarchy changed")) {
    // refresh rejected; running config retained — either revert the file or plan a restart
  }
}

Prevention

When it happens

Trigger: Editing mapred-queues.xml to add a queue, delete a queue, rename one, or reparent children, then running refresh-queues or calling QueueManager.refreshQueues(newConfiguration).

Common situations: Operators try to onboard a new tenant queue without a restart; a queue is retired while jobs still reference it; config drift between nodes causes one node's copy of mapred-queues.xml to differ.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/742092cff57cdebc. Report an issue: GitHub.

Appendix: source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/QueueManager.java:353

   * @throws IOException when queue configuration file is invalid.
   */
  synchronized void refreshQueues(Configuration conf,
      QueueRefresher schedulerRefresher)
      throws IOException {

    // Create a new configuration parser using the passed conf object.
    QueueConfigurationParser cp =
        getQueueConfigurationParser(conf, true, areAclsEnabled);

    /*
     * (1) Validate the refresh of properties owned by QueueManager. As of now,
     * while refreshing queue properties, we only check that the hierarchy is
     * the same w.r.t queue names, ACLs and state for each queue and don't
     * support adding new queues or removing old queues
     */
    if (!root.isHierarchySameAs(cp.getRoot())) {
      LOG.warn(MSG_REFRESH_FAILURE_WITH_CHANGE_OF_HIERARCHY);
      throw new IOException(MSG_REFRESH_FAILURE_WITH_CHANGE_OF_HIERARCHY);
    }

    /*
     * (2) QueueManager owned properties are validated. Now validate and
     * refresh the properties of scheduler in a single step.
     */
    if (schedulerRefresher != null) {
      try {
        schedulerRefresher.refreshQueues(cp.getRoot().getJobQueueInfo().getChildren());
      } catch (Throwable e) {
        StringBuilder msg =
            new StringBuilder(
                "Scheduler's refresh-queues failed with the exception : "
                    + StringUtils.stringifyException(e));
        msg.append("\n");
        msg.append(MSG_REFRESH_FAILURE_WITH_SCHEDULER_FAILURE);
        LOG.error(msg.toString());
        throw new IOException(msg.toString());

View on GitHub (pinned to 2add963021)