apache/hadoop · error · RuntimeException

Already started

Error message

Already started

What it means

MiniKdc.start() is not idempotent. It throws RuntimeException("Already started") when the internal simpleKdc field is already set, i.e. start() was called a second time on the same instance without an intervening stop(). The guard exists because the embedded Kerby SimpleKdcServer cannot be initialized twice.

Source

Thrown at hadoop-common-project/hadoop-minikdc/src/main/java/org/apache/hadoop/minikdc/MiniKdc.java:278

   * @return the realm of the MiniKdc.
   */
  public String getRealm() {
    return realm;
  }

  public File getKrb5conf() {
    krb5conf = new File(System.getProperty(JAVA_SECURITY_KRB5_CONF));
    return krb5conf;
  }

  /**
   * Starts the MiniKdc.
   *
   * @throws Exception thrown if the MiniKdc could not be started.
   */
  public synchronized void start() throws Exception {
    if (simpleKdc != null) {
      throw new RuntimeException("Already started");
    }
    simpleKdc = new SimpleKdcServer();
    prepareKdcServer();
    simpleKdc.init();
    resetDefaultRealm();
    simpleKdc.start();
    LOG.info("MiniKdc started.");
  }

  private void resetDefaultRealm() throws IOException {
    InputStream templateResource = new FileInputStream(
            getKrb5conf().getAbsolutePath());
    String content = IOUtil.readInput(templateResource);
    content = content.replaceAll("default_realm = .*\n",
            "default_realm = " + getRealm() + "\n");
    IOUtil.writeFile(content, getKrb5conf());
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Create a fresh MiniKdc instance per test: construct and start() in @Before, stop() in @After (wrapped in try/finally)
  2. Ensure the previous instance is stopped before starting again: stop() clears simpleKdc, after which start() works again on a new instance
  3. If reuse is required, track a started flag in your own harness and skip start() when already running

Example fix

// before
@Before public void setUp() { kdc.start(); } // second test -> Already started

// after
private MiniKdc kdc;
@Before public void setUp() throws Exception {
  kdc = new MiniKdc(MiniKdc.createConf(), workDir); // fresh instance each test
  kdc.start();
}
@After public void tearDown() { if (kdc != null) kdc.stop(); }
Defensive patterns

Strategy: validation

Validate before calling

private boolean kdcStarted = false;

public synchronized void ensureStarted(MiniKdc kdc) throws Exception {
  if (!kdcStarted) {
    kdc.start();
    kdcStarted = true;
  }
}

Try / catch

try {
  kdc.start();
} catch (RuntimeException e) {
  if ("Already started".equals(e.getMessage())) {
    return; // idempotent no-op
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling miniKdc.start() twice on the same instance: a @Before setUp() that starts the KDC while a previous test's stop() was skipped or failed, or helper code that tries to 'restart' the KDC by calling start() again.

Common situations: JUnit suites reusing a static MiniKdc across test methods; a failing test aborts @After tearDown so the KDC stays running and the next start() throws; harness code assuming start() is idempotent.

Related errors


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