{"record":{"id":"865d7223726b24a8","repo":"apache/druid","slug":"an-external-http-table-with-a-uri-must-also-provid-865d72","errorCode":null,"errorMessage":"An external HTTP table with a URI must also provide the corresponding columns","messagePattern":"An external HTTP table with a URI must also provide the corresponding columns","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/table/HttpInputSourceDefn.java","lineNumber":160,"sourceCode":"    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\"\n      );\n    }\n    if (hasTemplate) {\n\n      // Verify the template\n      templateMatcher(uriTemplate);\n\n      // Patch in a dummy URI so that validation of the rest of the fields\n      // will pass.\n      try {\n        sourceMap.put(\n            URIS_FIELD,\n            Collections.singletonList(new URI(\"https://bogus.com/file\"))\n        );\n      }\n      catch (Exception e) {\n        throw new ISE(e, \"URI parse failed\");","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/table/HttpInputSourceDefn.java#L142-L178","documentation":"Thrown by HttpInputSourceDefn.validate when an external HTTP table declares a URI but provides no column specification. The catalog requires explicit columns for URI-based HTTP tables so the format can map the fetched data to a known schema.","triggerScenarios":"A table with 'uris' set and a format present, but table.resolvedTable().spec().columns() is empty when validate runs.","commonSituations":"Specifying format but skipping the column list in a hand-authored spec; programmatically building a table and forgetting addColumn calls; templates exempt from this check so the mistake appears only when switching to fixed URIs.","solutions":["Define the columns list in the table spec, e.g. [{\"name\": \"t\", \"type\": \"string\"}, ...]","Ensure each column has a valid name and Druid type","Verify the serialized spec JSON actually contains the columns array"],"exampleFix":"// before\n{\"type\": \"http\", \"uris\": [...], \"format\": {\"type\": \"json\"}} // no columns\n// after\n... + \"columns\": [{\"name\": \"timestamp\", \"type\": \"long\"}, {\"name\": \"user\", \"type\": \"string\"}]","handlingStrategy":"validation","validationCode":"if (uris != null && (columns == null || columns.isEmpty())) { throw new IAE(\"columns required with URI\"); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always declare columns for external tables","Copy a known-good example spec","Validate spec with the catalog validate() before deploy"],"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"}