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
- Add a '{}' placeholder at the substitution point in the template, e.g. "https://host/data/{}.json"
- Replace any other placeholder syntax with exactly '{}'
- 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
- Always include exactly one {} in templates
- Don't use other placeholder syntaxes
- Test templates with a sample substitution
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
- External HTTP tables must provide either a URI or a %s prope
- External HTTP tables must provide only one of a URI or a %s
- An external HTTP table with a URI must also provide the corr
- An external HTTP table with a URI must also provide the corr
- One or more URIs is required in parameter %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6f59d4541deec888.
Report an issue: GitHub.