apache/druid · error · BadQueryContextException

Expected key [%s] to be in long format, but got [%s]

Error message

Expected key [%s] to be in long format, but got [%s]

What it means

QueryContexts.getAsLong(key, value) throws badValueException with this message when the context value is a String that cannot be parsed as a long. The getter tries Numbers.parseLong, then BigDecimal.longValueExact() to accept trivial decimals like "12.00" (mirroring Jackson coercion); failure of both produces this error naming the key and raw value.

Source

Thrown at processing/src/main/java/org/apache/druid/query/QueryContexts.java:420

  {
    if (value == null) {
      return null;
    } else if (value instanceof Number) {
      return ((Number) value).longValue();
    } else if (value instanceof String) {
      try {
        return Numbers.parseLong(value);
      }
      catch (NumberFormatException ignored) {

        // Attempt to handle trivial decimal values: 12.00, etc.
        // This mimics how Jackson will convert "12.00" to a Long on request.
        try {
          return new BigDecimal((String) value).longValueExact();
        }
        catch (Exception nfe) {
          // That didn't work either. Give up.
          throw badValueException(key, "in long format", value);
        }
      }
    }
    throw badTypeException(key, "a Long", value);
  }

  /**
   * Get the value of a context value as an {@code long}. The value is expected
   * to be {@code null}, a string or a {@code Number} object.
   */
  public static long getAsLong(
      final String key,
      final Object value,
      final long defaultValue
  )
  {
    Long val = getAsLong(key, value);
    return val == null ? defaultValue : val;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Change the context value to a plain long literal or JSON number: {"key": 9007199254740992} or "9007199254740992".
  2. Use a HumanReadableBytes-typed context key (getAsHumanReadableBytes) if you need units like "1GB".
  3. Strip units, commas, and whitespace before inserting the value.
  4. Catch the exception around getContextValue and use the documented default.

Example fix

// before
{"maxScatterGatherBytes": "800MB"}  // units -> IAE
// after
{"maxScatterGatherBytes": 838860800}
// or use a bytes-aware parameter elsewhere
Defensive patterns

Strategy: validation

Validate before calling

Object v = context.get(key);
if (v instanceof String) {
  try { new java.math.BigDecimal((String) v).longValueExact(); }
  catch (Exception e) { throw new IllegalArgumentException("Context key '" + key + "' must be a long, got: " + v); }
}

Type guard

boolean isParsableLong(Object v) {
  if (!(v instanceof String)) return v instanceof Number || v == null;
  try { new java.math.BigDecimal((String) v).longValueExact(); return true; } catch (Exception e) { return false; }
}

Try / catch

try {
  return query.getContextValue(key, defaultLong);
} catch (IllegalArgumentException e) {
  LOG.warn(e, "Non-long value for context key [%s], using default", key);
  return defaultLong;
}

Prevention

When it happens

Trigger: Calling QueryContexts.getAsLong(key, value) or query.getContextValue(key, long default) with a String like "abc", "12.5", "1e10", empty string, or values with units/separators that are not exactly representable as a long.

Common situations: Byte-size or timestamp context values written as "1GB", "2,000,000,000", or fractional numbers where a plain long is required; copy-pasted config containing units; locale-specific number formatting.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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