apache/druid · error · DruidException

(dynamic msg passed to DruidException.defensive)

Error message

%s (dynamic msg passed to DruidException.defensive)

What it means

DruidException.conditionalDefensive(condition, msg, args) throws a 'defensive' DruidException when the condition is false. Defensive exceptions mark internal invariants that should never be violated; if you see one, it indicates a bug or misuse of an internal API rather than an expected user-facing failure. The generic message text shown here is a placeholder — the real message is the dynamic msg argument passed at each call site.

Solutions

  1. Read the actual dynamic message in the exception — it names the violated condition.
  2. Capture the full stack trace and file a Druid bug with reproduction steps if the inputs are valid.
  3. Check your extension/custom code for misuse of internal Druid APIs.
  4. Upgrade to a newer Druid version where the invariant bug may already be fixed.

Example fix

// before: ignoring an unexpected state
handler.process(state); // state may be invalid
// after: validate inputs and report violations as bugs
if (state == null) {
  throw new IllegalArgumentException("state required");
}
handler.process(state);
Defensive patterns

Strategy: try-catch

Try / catch

try { druidInternalCall(args); } catch (DruidException e) {
  if (e.getPersona() == DruidException.Persona.DEVELOPER) {
    // defensive violation: capture for a bug report
    log.error("Druid invariant violated", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling any Druid API that internally calls DruidException.conditionalDefensive(cond, ...) where cond evaluates to false — i.e., an internal precondition/invariant check failed.

Common situations: Bugs in Druid or extension code hitting an impossible state; misuse of internal APIs from custom extensions; race conditions or corrupted inputs violating assumed invariants.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/353dd52ec2f75db1. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/error/DruidException.java:205

   */
  public static DruidException defensive(Throwable cause, String format, Object... args)
  {
    return defensive().build(cause, format, args);
  }

  /**
   * Build a "defensive" exception, this is an exception that should never actually be triggered. Throw to
   * allow messages to be seen by developers
   *
   * @param condition - boolean condition to validate
   * @param msg - passed through to InvalidInput.exception()
   * @param args - passed through to InvalidInput.exception()
   */
  @SuppressWarnings("unused")
  public static void conditionalDefensive(boolean condition, String msg, Object... args)
  {
    if (!condition) {
      throw defensive(msg, args);
    }
  }

  private final Persona targetPersona;
  private final Category category;
  private final String errorCode;
  protected final Map<String, String> context = new LinkedHashMap<>();

  private DruidException(
      Throwable cause,
      final String errorCode,
      Persona targetPersona,
      Category category,
      final String message
  )
  {
    this(cause, errorCode, targetPersona, category, message, false);
  }

View on GitHub (pinned to 9b90983fd2)