{"record":{"id":"009c48fab96fb331","repo":"apache/druid","slug":"external-http-tables-must-provide-either-a-uri-or","errorCode":null,"errorMessage":"External HTTP tables must provide either a URI or a %s property","messagePattern":"External HTTP tables must provide either a URI or a (.+?) property","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/table/HttpInputSourceDefn.java","lineNumber":143,"sourceCode":"\n  @Override\n  protected Class<? extends InputSource> inputSourceClass()\n  {\n    return HttpInputSource.class;\n  }\n\n  @Override\n  public void validate(ResolvedExternalTable table)\n  {\n    final Map<String, Object> sourceMap = table.inputSourceMap;\n    final boolean hasUri = sourceMap.containsKey(URIS_FIELD);\n    final String uriTemplate = table.resolvedTable().stringProperty(URI_TEMPLATE_PROPERTY);\n    final boolean hasTemplate = uriTemplate != null;\n    final boolean hasFormat = table.inputFormatMap != null;\n    final boolean hasColumns = !CollectionUtils.isNullOrEmpty(table.resolvedTable().spec().columns());\n\n    if (!hasUri && !hasTemplate) {\n      throw new IAE(\n          \"External HTTP tables must provide either a URI or a %s property\",\n          URI_TEMPLATE_PROPERTY\n      );\n    }\n    if (hasUri && hasTemplate) {\n      throw new IAE(\n          \"External HTTP tables must provide only one of a URI or a %s property\",\n          URI_TEMPLATE_PROPERTY\n      );\n    }\n    if (hasUri && !hasFormat) {\n      throw new IAE(\n          \"An external HTTP table with a URI must also provide the corresponding format\"\n      );\n    }\n    if (hasUri && !hasColumns) {\n      throw new IAE(\n          \"An external HTTP table with a URI must also provide the corresponding columns\"","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/table/HttpInputSourceDefn.java#L125-L161","documentation":"Thrown by HttpInputSourceDefn.validate when an external HTTP table specifies neither a URI nor the uriTemplate property. An HTTP input source must know which endpoint(s) to fetch data from, so at least one addressing mechanism is mandatory.","triggerScenarios":"Validating a catalog HTTP external table where the resolved table has no 'uris' field in its input source map and no uriTemplate table property set.","commonSituations":"Creating an external HTTP table spec and forgetting to fill in the address entirely; copying a template-based table definition and deleting both the template and URI fields; programmatic table construction that skipped the location property.","solutions":["Set the 'uris' field on the HTTP input source, e.g. [\"https://example.com/data.json\"]","Alternatively set the uriTemplate property on the table for parameterized URLs","Re-check the table definition JSON to confirm the address field survived serialization"],"exampleFix":"// before\n{\"type\": \"http\"}\n// after\n{\"type\": \"http\", \"uris\": [\"https://example.com/data.json\"]}","handlingStrategy":"validation","validationCode":"boolean ok = inputSource.getUris() != null && !inputSource.getUris().isEmpty() || tableProps.containsKey(\"uriTemplate\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always define either uris or uriTemplate for HTTP tables","Review table JSON before submitting","Use schema-aware editors that flag empty sources"],"tags":["catalog","http","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}