apache/druid · error · IAE

Value [%s] for property %s must include a '{}' placeholder

Error message

Value [%s] for property %s must include a '{}' placeholder

What it means

Thrown by HttpInputSourceDefn.templateMatcher when the uriTemplate property value does not contain the required '{}' placeholder. Templates work by replacing the first '{}' occurrence with each concrete URI string, so a template without the placeholder is unusable.

Source

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

  @Override
  protected void auditInputSource(Map<String, Object> jsonMap)
  {
    // A partial table may not include the URI parameter. For example, we might
    // define an HTTP input source "with URIs to be named later." Even though the
    // input source is partial, we still want to validate the other parameters.
    // The HttpInputSource will fail if the URIs is not set. So, we have to make
    // up a fake one just so we can validate the other fields by asking the
    // input source to deserialize itself from the jsonMap.
    jsonMap.putIfAbsent(URIS_PARAMETER, "http://bogus.com");
  }

  private Matcher templateMatcher(String uriTemplate)
  {
    Pattern p = Pattern.compile("\\{}");
    Matcher m = p.matcher(uriTemplate);
    if (!m.find()) {
      throw new IAE(
          "Value [%s] for property %s must include a '{}' placeholder",
          uriTemplate,
          URI_TEMPLATE_PROPERTY
      );
    }
    return m;
  }

  @Override
  protected List<ParameterDefn> adHocTableFnParameters()
  {
    return CatalogUtils.concatLists(URI_PARAMS, CatalogUtils.concatLists(USER_PWD_PARAMS, HEADERS_PARAMS));
  }

  @Override
  protected void convertArgsToSourceMap(Map<String, Object> jsonMap, Map<String, Object> args)
  {
    jsonMap.put(InputSource.TYPE_PROPERTY, HttpInputSource.TYPE_KEY);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Add a '{}' placeholder at the substitution point in the template, e.g. "https://host/data/{}.json"
  2. Replace any other placeholder syntax with exactly '{}'
  3. Escape nothing: '{}' is matched literally by the validator

Example fix

// before
uriTemplate = "https://example.com/data"
// after
uriTemplate = "https://example.com/data/{}.json"
Defensive patterns

Strategy: validation

Validate before calling

if (uriTemplate != null && !uriTemplate.contains("{}")) { throw new IAE("template must contain {}"); }

Try / catch

try { validate(t); } catch (IAE e) { if (e.getMessage().contains("placeholder")) { /* fix template */ } else { throw e; } }

Prevention

When it happens

Trigger: validate() calls templateMatcher on the uriTemplate property, or convertUriTemplateArgs (via convertCompletedTable) applies it; the regex \{} finds no match.

Common situations: Writing a template like "https://host/files" instead of "https://host/{}.json"; using '*' or '{uri}' as the placeholder out of habit from other template systems; trimming the placeholder accidentally in config.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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