{"record":{"id":"b90634c268059bcf","repo":"apache/druid","slug":"failed-to-apply-webclientoptions-to-webclientoptio","errorCode":null,"errorMessage":"Failed to apply webClientOptions to WebClientOptions. Check that all property names and values are valid. Properties provided: %s","messagePattern":"Failed to apply webClientOptions to WebClientOptions\\. Check that all property names and values are valid\\. Properties provided: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/common/httpclient/vertx/DruidKubernetesVertxHttpClientFactory.java","lineNumber":63,"sourceCode":"      DruidKubernetesVertxHttpClientConfig httpClientConfig,\n      ObjectMapper objectMapper\n  )\n  {\n    super(createVertxInstance(httpClientConfig));\n    this.httpClientConfig = httpClientConfig;\n    this.objectMapper = objectMapper;\n  }\n\n  @Override\n  protected void additionalConfig(WebClientOptions options)\n  {\n    if (!httpClientConfig.getWebClientOptions().isEmpty()) {\n      try {\n        LOG.info(\"Applying additional WebClientOptions from configuration: %s\", httpClientConfig.getWebClientOptions());\n        objectMapper.updateValue(options, httpClientConfig.getWebClientOptions());\n      }\n      catch (Exception e) {\n        throw new RuntimeException(\n            \"Failed to apply webClientOptions to WebClientOptions. \"\n            + \"Check that all property names and values are valid. \"\n            + \"Properties provided: \" + httpClientConfig.getWebClientOptions(),\n            e\n        );\n      }\n    }\n  }\n\n  /**\n   * Adapted from fabric8 kubernetes-client 7.1.0. We bring this here so we can customize thread pool sizes\n   * and force usage of daemon threads.\n   */\n  private static Vertx createVertxInstance(final DruidKubernetesVertxHttpClientConfig httpClientConfig)\n  {\n    // fabric8 disables the async DNS resolver while creating Vertx.\n    // I'm not sure if we really need to do this, but I'm keeping it to align behavior with upstream.\n    final String originalDnsResolverProperty = System.getProperty(ResolverProvider.DISABLE_DNS_RESOLVER_PROP_NAME);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/common/httpclient/vertx/DruidKubernetesVertxHttpClientFactory.java#L45-L81","documentation":"Thrown by DruidKubernetesVertxHttpClientFactory.additionalConfig when applying the configured webClientOptions map onto the Vert.x WebClientOptions object via Jackson's objectMapper.updateValue fails. It wraps the underlying exception and tells the operator that some property name or value in druid.client.http.webClientOptions (or equivalent HttpClientConfig.webClientOptions) is not a valid settable property of WebClientOptions.","triggerScenarios":"HttpClientConfig.getWebClientOptions() is non-empty and objectMapper.updateValue(options, webClientOptions) throws — typically an unknown option key (typo or property not existing in the Vert.x version in use) or a value of the wrong type (e.g. string where an int/boolean is required).","commonSituations":"Typos in option names like 'connectTimeout' vs actual Vert.x property names; options introduced in newer Vert.x versions than the one bundled with this Druid build; passing nested structures as flat strings; copy-pasting options from io.vertx.core.http.HttpClientOptions (old class) that no longer exist on WebClientOptions.","solutions":["Read the wrapped cause in the exception stack trace to find the exact offending property, then fix or remove it from the webClientOptions map","Validate each key against the WebClientOptions setter list for the Vert.x version bundled with your Druid build","Check value types (numeric/boolean options must be the right JSON type)","If a key exists only in newer Vert.x, remove it until upgrading Druid"],"exampleFix":"// before (invalid/misspelled option)\ndruid.client.http.webClientOptions='{\"connectTimout\": 5000}'\n\n// after\ndruid.client.http.webClientOptions='{\"setConnectTimeout\": 5000}'","handlingStrategy":"validation","validationCode":"// Validate webClientOptions keys against WebClientOptions setters before configuring\nObjectMapper om = new ObjectMapper();\nWebClientOptions probe = new WebClientOptions();\nfor (String key : httpClientConfig.getWebClientOptions().keySet()) {\n    // updateValue on a throwaway instance to detect bad keys early\n    try {\n        om.updateValue(probe, Map.of(key, httpClientConfig.getWebClientOptions().get(key)));\n    } catch (Exception e) {\n        throw new IllegalArgumentException(\"Invalid webClientOptions key: \" + key, e);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    httpClientFactory.applyConfig(options);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Failed to apply webClientOptions\")) {\n        LOG.error(e, \"Bad druid.client.http.webClientOptions; starting client with defaults\");\n        // fall back to default options instead of aborting startup\n    } else {\n        throw e;\n    }\n}","preventionTips":["Verify each key against the exact Vert.x WebClientOptions setter names for your Druid version","Use JSON-native value types (numbers/booleans) for the options map","Test options in a staging Overlord before rolling out"],"tags":["http-client","vertx","configuration","druid"],"backgroundTag":"invalid-config-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}