{"record":{"id":"d1a60cf6e576fa16","repo":"apache/druid","slug":"schemaregistrybasedprotobufbytesdecoder-requires-n","errorCode":null,"errorMessage":"SchemaRegistryBasedProtobufBytesDecoder requires non-null URLs","messagePattern":"SchemaRegistryBasedProtobufBytesDecoder requires non-null URLs","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/SchemaRegistryBasedProtobufBytesDecoder.java","lineNumber":86,"sourceCode":"      @JsonProperty(\"config\") @Nullable Map<String, Object> config,\n      @JsonProperty(\"headers\") @Nullable Map<String, Object> headers,\n      @JacksonInject @Json ObjectMapper jsonMapper\n  )\n  {\n    this.url = url;\n    this.capacity = capacity == null ? Integer.MAX_VALUE : capacity;\n    this.urls = urls;\n    this.config = config;\n    this.headers = headers;\n    this.jsonMapper = jsonMapper;\n\n    if (StringUtils.isNotEmpty(this.url)) {\n      LOGGER.warn(\"\\\"url\\\" is deprecated, use \\\"urls\\\" instead\");\n    }\n\n    final var baseUrls = StringUtils.isNotEmpty(this.url) ? Collections.singletonList(this.url) : this.urls;\n    if (baseUrls == null) {\n      throw new IAE(\"SchemaRegistryBasedProtobufBytesDecoder requires non-null URLs\");\n    }\n\n    this.registry = new CachedSchemaRegistryClient(\n        baseUrls,\n        this.capacity,\n        Collections.singletonList(new ProtobufSchemaProvider()),\n        DynamicConfigProviderUtils.extraConfigAndSetObjectMap(\n            config,\n            DRUID_DYNAMIC_CONFIG_PROVIDER_KEY,\n            this.jsonMapper\n        ),\n        DynamicConfigProviderUtils.extraConfigAndSetStringMap(\n            headers,\n            DRUID_DYNAMIC_CONFIG_PROVIDER_KEY,\n            this.jsonMapper\n        )\n    );\n  }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/SchemaRegistryBasedProtobufBytesDecoder.java#L68-L104","documentation":"SchemaRegistryBasedProtobufBytesDecoder builds a Confluent CachedSchemaRegistryClient from configured registry endpoints. The 'url' property is deprecated in favor of 'urls'; if neither yields a non-empty base URL list (both null/empty), the constructor throws IllegalArgumentException because it cannot create a registry client without endpoints.","triggerScenarios":"Instantiating the decoder (e.g. via JSON deserialization of the kafka ingestion spec) with neither 'urls' set nor the deprecated 'url' set — both absent or empty strings/lists.","commonSituations":"Missing schemaRegistry config in the input format spec after migration from 'url' to 'urls'; a typo like 'url1' or an empty urls: [] in the supervisor spec.","solutions":["Set the 'urls' property in the schemaRegistry decoder config to a list of schema registry endpoints, e.g. [\"http://registry:8081\"]","If migrating from 'url', move the value into 'urls' (the old key still works but is deprecated)","Validate the ingestion spec's inputFormat.schemaRegistry section before submitting the supervisor"],"exampleFix":"// before\n\"schemaRegistry\": {\"urls\": []}\n// after\n\"schemaRegistry\": {\"urls\": [\"http://schema-registry:8081\"]}","handlingStrategy":"validation","validationCode":"Object urls = spec.path(\"schemaRegistry.urls\");\nObject url = spec.path(\"schemaRegistry.url\");\nboolean empty = (urls == null || ((List<?>) urls).isEmpty()) && (url == null || url.toString().isEmpty());\nif (empty) throw new IllegalArgumentException(\"schemaRegistry requires non-empty 'urls'\");","typeGuard":"boolean hasRegistryUrls(Map<String, Object> schemaRegistry) {\n  List<?> urls = (List<?>) schemaRegistry.get(\"urls\");\n  String url = (String) schemaRegistry.get(\"url\");\n  return (urls != null && !urls.isEmpty()) || (url != null && !url.isEmpty());\n}","tryCatchPattern":"try {\n  SchemaRegistryBasedProtobufBytesDecoder decoder =\n      mapper.convertValue(schemaRegistryCfg, SchemaRegistryBasedProtobufBytesDecoder.class);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"requires non-null URLs\")) {\n    throw new SpecValidationException(\"Set schemaRegistry.urls in the input format spec\");\n  }\n  throw e;\n}","preventionTips":["Always set 'urls' with at least one registry endpoint in the inputFormat spec","Lint ingestion specs (JSON schema validation) before submitting supervisors","Migrate off the deprecated 'url' key so a single config path is validated"],"tags":["configuration","schema-registry","argument-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-17T15:17:12.973Z"}