Environment:Apache Druid Druid Cluster Api
| Knowledge Sources | |
|---|---|
| Domains | Druid Cluster, REST API, Capability Detection, Runtime Configuration |
| Last Updated | 2026-02-10 10:00 GMT |
Overview
The Druid Cluster API environment defines the running Druid cluster endpoints, capability detection protocol, and runtime configuration that the web console expects to interact with at runtime.
Description
The Apache Druid web console communicates with a running Druid cluster through a series of REST API endpoints exposed by the Router, Coordinator, Overlord, and Broker services. On startup, the console executes a capability detection sequence (implemented in capabilities.ts) that probes the cluster to determine which features are available: SQL query support, native query support, management proxy access, MSQ task engine, and DART engine.
The detection uses a 15-second timeout (STATUS_TIMEOUT = 15000) for each probe. Based on the results, the console enters one of several capability modes: full, no-sql, no-proxy, no-sql-no-proxy, coordinator-overlord, coordinator, or overlord. These modes determine which views and features are enabled in the UI.
Additionally, the console uses a doctor checks system (doctor-checks.tsx) that validates cluster health by verifying runtime properties are consistent across nodes, checking Java version compatibility, confirming the sampler works, and detecting overfull historicals.
Runtime configuration is injected via window.consoleConfig, allowing operators to customize the base URL, set custom headers for authentication proxies, inject default query context, and override documentation links.
Usage
Use this environment specification when:
- Setting up a Druid cluster that will serve the web console
- Troubleshooting why certain console features are disabled or unavailable
- Configuring the console behind a reverse proxy or load balancer
- Validating that the management proxy is correctly enabled on the Router
- Understanding which API endpoints the console depends on
System Requirements
| Category | Requirement | Notes |
|---|---|---|
| Java | 8u92+, 11, or 17 | Checked in doctor-checks.tsx:99-108
|
| Router Port (HTTP) | 8888 | Default; auto-detected by webpack.config.mjs
|
| Router Port (HTTPS) | 9088 | Auto-detected when druid_host ends with :9088
|
| Coordinator Port | 8081 | Standard Druid coordinator HTTP port |
| File Encoding | UTF-8 | Recommended; checked by doctor-checks |
| User Timezone | UTC | Recommended; must be consistent across all nodes |
| Capability Timeout | 15000ms | Capabilities.STATUS_TIMEOUT in capabilities.ts:80
|
Dependencies
System Packages
- A running Apache Druid cluster with at minimum a Router node (for full console functionality, Coordinator and Overlord must also be accessible)
- ZooKeeper ensemble (required by the Druid cluster itself)
- Network connectivity from the browser to the Router's HTTP/HTTPS port
Language Packages
- axios ^1.12.0 -- used by the
Apisingleton for all HTTP requests to the cluster - druid-query-toolkit ^1.2.2 -- provides
QueryRunnerfor SQL and native query execution
Credentials
No built-in authentication is required by the console itself. The following runtime configuration options are available via window.consoleConfig:
| Property | Type | Purpose |
|---|---|---|
baseURL |
string | Override the base URL for all API requests (for reverse proxy setups) |
customHeaderName |
string | Single custom header name to attach to every AJAX request |
customHeaderValue |
string | Value for the single custom header |
customHeaders |
Record<string, string> | Multiple custom headers to attach to every AJAX request |
baseQueryContext |
QueryContext | Base context merged into all query requests |
defaultQueryContext |
QueryContext | Default context set on new query tabs |
mandatoryQueryContext |
QueryContext | Context properties forced on every query request |
serverQueryContext |
QueryContext | Default context reported by the server |
title |
string | Custom page title |
linkOverrides |
Links | Override documentation links |
localStorageNamespace |
string | Namespace localStorage keys (for multi-cluster proxy setups) |
Quick Install
# Start a minimal Druid cluster (quickstart mode)
cd druid-distribution/target/apache-druid-*
./bin/start-druid
# Verify the Router is accessible
curl http://localhost:8888/status
# Verify the management proxy is enabled
curl http://localhost:8888/proxy/enabled
# A 400 response indicates the proxy IS enabled (see capabilities.ts)
# Verify SQL endpoint
curl -X POST http://localhost:8888/druid/v2/sql \
-H 'Content-Type: application/json' \
-d '{"query": "SELECT 1337"}'
# Verify MSQ task engine
curl http://localhost:8888/druid/v2/sql/task/enabled
# Verify DART engine availability
curl http://localhost:8888/druid/v2/sql/engines
Code Evidence
Capability detection timeout and probe (web-console/src/helpers/capabilities.ts:80-130):
export class Capabilities {
static STATUS_TIMEOUT = 15000;
static async detectQueryType(): Promise<QueryType | undefined> {
// Check SQL endpoint
try {
await Api.instance.post(
'/druid/v2/sql?capabilities',
{ query: 'SELECT 1337', context: { timeout: Capabilities.STATUS_TIMEOUT } },
{ timeout: Capabilities.STATUS_TIMEOUT },
);
} catch (e) {
const status = e.response?.status;
if (status !== 405 && status !== 404) {
return; // other failure
}
// ... falls through to native query check
}
return 'nativeAndSql';
}
Management proxy detection trick (web-console/src/helpers/capabilities.ts:132-144):
static async detectManagementProxy(): Promise<boolean> {
try {
await Api.instance.get(`/proxy/enabled?capabilities`, {
timeout: Capabilities.STATUS_TIMEOUT,
});
} catch (e) {
const status = e.response?.status;
// If we detect error code 400 the management proxy is enabled but just does not
// know about the recently added /proxy/enabled route so treat this as a win.
return status === 400;
}
return true;
}
Capability modes (web-console/src/helpers/capabilities.ts:25-34):
export type CapabilitiesMode = 'full' | 'no-sql' | 'no-proxy';
export type CapabilitiesModeExtended =
| 'full'
| 'no-sql'
| 'no-proxy'
| 'no-sql-no-proxy'
| 'coordinator-overlord'
| 'coordinator'
| 'overlord';
Java version check (web-console/src/dialogs/doctor-dialog/doctor-checks.tsx:99-108):
if (
properties['java.specification.version'] &&
properties['java.specification.version'] !== '1.8' &&
properties['java.specification.version'] !== '11' &&
properties['java.specification.version'] !== '17'
) {
controls.addSuggestion(
`It looks like are running Java ${properties['java.runtime.version']}. Druid officially supports Java 8u92+, 11, or 17`,
);
}
Required runtime property check (web-console/src/dialogs/doctor-dialog/doctor-checks.tsx:40-52):
const RUNTIME_PROPERTIES_ALL_NODES_MUST_AGREE_ON: string[] = [
'user.timezone',
'druid.zk.service.host',
];
const RUNTIME_PROPERTIES_MASTER_NODES_SHOULD_AGREE_ON: string[] = [
'druid.metadata.storage.type',
'druid.metadata.storage.connector.connectURI',
];
Management proxy property check (web-console/src/dialogs/doctor-dialog/doctor-checks.tsx:93-97):
if (properties['druid.router.managementProxy.enabled'] !== 'true') {
controls.addIssue(
`The Router's "druid.router.managementProxy.enabled" is not reported as "true".`
);
}
Runtime config via window.consoleConfig (web-console/src/entry.tsx:43-75):
interface ConsoleConfig {
title?: string;
baseURL?: string;
customHeaderName?: string;
customHeaderValue?: string;
customHeaders?: Record<string, string>;
baseQueryContext?: QueryContext;
defaultQueryContext?: QueryContext;
mandatoryQueryContext?: QueryContext;
serverQueryContext?: QueryContext;
linkOverrides?: Links;
localStorageNamespace?: string;
}
const consoleConfig: ConsoleConfig = (window as any).consoleConfig;
Common Errors
| Error Message | Cause | Solution |
|---|---|---|
| Console stuck on loading / capabilities undefined | All capability probes failed; Router unreachable | Verify the Router is running on port 8888 and accessible from the browser |
| SQL features disabled (no-sql mode) | /druid/v2/sql returns 405 or 404 |
Ensure druid.sql.enable=true in broker runtime properties and that a Broker is running
|
| Coordinator/Overlord panels missing (no-proxy mode) | Management proxy not enabled on Router | Set druid.router.managementProxy.enabled=true in the Router's runtime properties
|
Doctor check: nodes disagree on user.timezone |
Inconsistent JVM timezone settings across cluster nodes | Set -Duser.timezone=UTC on all Druid service JVMs
|
Doctor check: nodes disagree on druid.zk.service.host |
ZooKeeper connection string mismatch | Ensure all nodes use the same druid.zk.service.host value
|
/proxy/enabled returns 404 (not 400) |
Management proxy is genuinely disabled | Enable the management proxy or accept reduced console functionality |
Compatibility Notes
- The management proxy detection relies on a 400 status code trick: the
/proxy/enabledendpoint was added recently, so older Druid versions with the proxy enabled return 400 (proxy active but unknown route) rather than 200. The console treats 400 as success. - MSQ task engine detection requires Druid 24.0+ where
/druid/v2/sql/task/enabledwas introduced. - DART engine detection requires a Druid version that exposes
/druid/v2/sql/engineswith anmsq-dartentry. - The console supports degraded modes gracefully -- it disables UI features that require unavailable capabilities rather than failing entirely.
- The
window.consoleConfigmechanism allows the console to work behind enterprise authentication proxies by injecting custom headers without modifying the console source.