apache/druid · error · ISE

Failed read map from headers json

Error message

Failed read map from headers json

What it means

Thrown by HttpInputSourceDefn.convertHeaderArg when the requestHeaders argument (a JSON string expected to deserialize into Map<String,String>) cannot be parsed by Jackson, wrapping the JsonProcessingException as an IllegalStateException. HTTP tables may attach request headers, and they must be valid JSON object syntax.

Source

Thrown at server/src/main/java/org/apache/druid/catalog/model/table/HttpInputSourceDefn.java:316

    if (uris != null) {
      jsonMap.put(URIS_FIELD, CatalogUtils.stringListToUriList(uris));
    }
  }

  /**
   * URIs in SQL is in the form of a string that contains a comma-delimited
   * set of URIs. Done since SQL doesn't support array scalars.
   */
  private void convertHeaderArg(Map<String, Object> jsonMap, Map<String, Object> args)
  {
    String requestHeaders = CatalogUtils.getString(args, HEADERS);
    Map<String, String> headersMap;
    if (requestHeaders != null) {
      try {
        headersMap = DefaultObjectMapper.INSTANCE.readValue(requestHeaders, new TypeReference<>() {});
      }
      catch (JsonProcessingException e) {
        throw new ISE("Failed read map from headers json");
      }
      jsonMap.put(HEADERS_FIELD, headersMap);
    }

  }

  /**
   * Convert the user name and password. All are SQL strings. Passwords must be in
   * the form of a password provider, so do the needed conversion. HTTP provides
   * two kinds of passwords (plain test an reference to an env var), but at most
   * one can be provided.
   */
  private void convertUserPasswordArgs(Map<String, Object> jsonMap, Map<String, Object> args)
  {
    String user = CatalogUtils.getString(args, USER_PARAMETER);
    if (user != null) {
      jsonMap.put(USERNAME_FIELD, user);
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Supply headers as a valid JSON object string, e.g. "{\"Authorization\": \"Bearer tok\"}"
  2. Validate the JSON with a parser/JSON tool before submitting
  3. Ensure all values are strings and the top level is an object, not an array

Example fix

// before
requestHeaders = "Authorization: Bearer tok"
// after
requestHeaders = "{\"Authorization\": \"Bearer tok\"}"
Defensive patterns

Strategy: validation

Validate before calling

try { new ObjectMapper().readTree(headersJson); } catch (Exception e) { throw new IAE("headers must be a JSON object"); }

Type guard

boolean isJsonStringObject(String s) { try { return DefaultObjectMapper.INSTANCE.readValue(s, new TypeReference<Map<String,String>>(){}) != null; } catch (Exception e) { return false; } }

Try / catch

try { convert(headers); } catch (ISE e) { if (e.getMessage().contains("headers json")) { /* show JSON syntax guidance to user */ } else { throw e; } }

Prevention

When it happens

Trigger: convertArgsToSourceMap or convertCompletedTable passes a requestHeaders string to convertHeaderArg and DefaultObjectMapper.readValue throws JsonProcessingException (malformed JSON, wrong shape like an array, or non-string values).

Common situations: Users typing header text like 'Authorization: Bearer x' instead of a JSON object; single quotes around keys/values; nested or non-string values; truncated JSON from copy-paste.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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