{"record":{"id":"ed9c4c275c86acbb","repo":"apache/druid","slug":"double-dot-in-property-s","errorCode":null,"errorMessage":"Double dot in property: %s","messagePattern":"Double dot in property: (.+?)","errorType":"validation","errorClass":"ProvisionException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/guice/JsonConfigurator.java","lineNumber":237,"sourceCode":"\n  private static void hieraricalPutValue(\n      String propertyPrefix,\n      String originalProperty,\n      String property,\n      Object value,\n      Map<String, Object> targetMap\n  )\n  {\n    int dotIndex = property.indexOf('.');\n    // Always put property with name even if it is of form a.b. This will make sure the property is available for classes\n    // where JsonProperty names are of the form a.b\n    // Note:- this will cause more than required properties to be present in the jsonMap.\n    targetMap.put(property, value);\n    if (dotIndex < 0) {\n      return;\n    }\n    if (dotIndex == 0) {\n      throw new ProvisionException(StringUtils.format(\"Double dot in property: %s\", originalProperty));\n    }\n    if (dotIndex == property.length() - 1) {\n      throw new ProvisionException(StringUtils.format(\"Dot at the end of property: %s\", originalProperty));\n    }\n    String nestedKey = property.substring(0, dotIndex);\n    Object nested = targetMap.computeIfAbsent(nestedKey, k -> new HashMap<String, Object>());\n    if (!(nested instanceof Map)) {\n      // Clash is possible between properties, which are used to configure different objects: e. g.\n      // druid.emitter=parametrized is used to configure Emitter class, and druid.emitter.parametrized.xxx=yyy is used\n      // to configure ParametrizedUriEmitterConfig object. So skipping xxx=yyy key-value pair when configuring Emitter\n      // doesn't make any difference. That is why we just log this situation, instead of throwing an exception.\n      log.info(\n          \"Skipping property [%s]: one of it's prefixes [%s] is also used as a property key.\",\n          originalProperty,\n          propertyPrefix\n      );\n      return;\n    }","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/guice/JsonConfigurator.java#L219-L255","documentation":"JsonConfigurator flattens dotted runtime properties (druid.emitter.http.flushThreshold) into nested JSON maps via hieraricalPutValue. A dot at position 0 of a property key means the key starts with a dot or contains consecutive dots ('..'), producing an empty nested key segment. Druid throws ProvisionException 'Double dot in property' because it cannot build a valid nested map from such a key.","triggerScenarios":"hieraricalPutValue is called recursively from configurate for each runtime property; when indexOf('.') == 0 for the current suffix (key begins with '.' or contains '..'), it throws immediately.","commonSituations":"Typo in runtime.properties like 'druid..emitter=...' or a stray leading dot from scripted property generation or environment-variable-to-property conversion scripts.","solutions":["Locate the property named in the error and remove the extra dot(s) so the key is a valid dotted path like druid.emitter.http.flushThreshold","Check any script or template that generates runtime.properties for accidental '..' or leading-dot output","Restart the Druid process and confirm the error is gone"],"exampleFix":"// before (runtime.properties)\ndruid..emitter=parametrized\n// after\ndruid.emitter=parametrized","handlingStrategy":"validation","validationCode":"for (String key : props.stringPropertyNames()) {\n  if (key.startsWith(\".\") || key.contains(\"..\")) throw new IllegalArgumentException(\"Malformed property key: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try { injector = Guice.createInjector(...); } catch (ProvisionException e) { if (e.getMessage().contains(\"Double dot\")) log.error(\"Fix dotted property key\"); throw e; }","preventionTips":["Never hand-edit generated properties files; use templating that validates keys","Add a startup pre-check script that rejects keys with '..' or leading dots","Keep one canonical source of truth for runtime.properties"],"tags":["guice","configuration","property-parsing","startup"],"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-14T11:17:12.474Z"}