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
- Create a fresh MiniKdc instance per test: construct and start() in @Before, stop() in @After (wrapped in try/finally)
- Ensure the previous instance is stopped before starting again: stop() clears simpleKdc, after which start() works again on a new instance
- 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
- Construct a fresh MiniKdc per test in @Before and stop() it in @After with try/finally
- Never assume start() is idempotent — track lifecycle state in your harness
- Make tearDown resilient: even if a test fails, stop() must run so the next test starts clean
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
- Cannot create directory %s
- Specified work directory does not exists: %s
- Specified configuration does not exists: %s
- Cannot rename KDC's krb5conf to %s
- Missing configuration properties: %s
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/68e080715659adf6.
Report an issue: GitHub.