perwendel/spark · error · IllegalStateException
Server has not been properly initialized
Error message
Server has not been properly initialized
What it means
Service.awaitInitialization() blocks until the embedded server's init latch is released, letting users wait for server startup before proceeding (e.g. in tests). If the Service was never initialized — no route mapping occurred, so 'initialized' is false — waiting would block forever, so Spark throws IllegalStateException instead.
Solutions
- Map at least one route (get/post/staticFiles etc.) before calling awaitInitialization().
- Call init() (or ensure routes are mapped) and only then awaitInitialization().
- If the server may not be started, check your own bootstrap state before relying on awaitInitialization.
Example fix
// before
Spark.awaitInitialization(); // too early
Spark.get("/hello", (req, res) -> "hi");
// after
Spark.get("/hello", (req, res) -> "hi");
Spark.init();
Spark.awaitInitialization(); Defensive patterns
Strategy: try-catch
Validate before calling
if (routesMapped) { // your own bootstrap flag
Spark.awaitInitialization();
} Try / catch
try {
Spark.awaitInitialization();
} catch (IllegalStateException e) {
LOG.warn("Server was never initialized; skipping wait");
} Prevention
- Always map at least one route before awaiting initialization.
- In tests, call init() before awaitInitialization().
- Centralize startup order: map routes -> init -> awaitInitialization.
When it happens
Trigger: Calling Spark.awaitInitialization() (or Service.awaitInitialization()) before any route mapping call has marked the service initialized, e.g. calling it at the top of main() before mapping any routes, or on a Service instance that never had routes registered.
Common situations: Test setup code calling awaitInitialization() before defining routes; copy-pasted boilerplate in the wrong order; calling awaitInitialization in a wrapper library that never maps routes itself.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- This must be done after route mapping has begun
- This must be done before route mapping has begun
- HttpServletRequest cannot be null.
- Must provide a keystore file to run secured
- WebSockets are only supported in the embedded server
AI-assisted analysis of perwendel/spark@1973e402f5 (2026-09-10).
Data as JSON: /api/errors/35bb10bf6b105979.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/spark/Service.java:492
*/
public synchronized void notFound(Route route) {
CustomErrorPages.add(404, route);
}
/**
* Maps 500 internal server errors to the provided route.
*/
public synchronized void internalServerError(Route route) {
CustomErrorPages.add(500, route);
}
/**
* Waits for the spark server to be initialized.
* If it's already initialized will return immediately
*/
public void awaitInitialization() {
if (!initialized) {
throw new IllegalStateException("Server has not been properly initialized");
}
try {
initLatch.await();
} catch (InterruptedException e) {
LOG.info("Interrupted by another thread");
Thread.currentThread().interrupt();
}
}
private void throwBeforeRouteMappingException() {
throw new IllegalStateException(
"This must be done before route mapping has begun");
}
private boolean hasMultipleHandlers() {
return webSocketHandlers != null;
}View on GitHub (pinned to 1973e402f5)