apache/druid · error · ProvisionException

Dot at the end of property: %s

Error message

Dot at the end of property: %s

What it means

hieraricalPutValue builds nested maps from dotted property keys; a key ending with a dot would produce an empty final segment, which cannot map to a config field. Druid throws ProvisionException 'Dot at the end of property' to fail fast on the malformed key.

Source

Thrown at processing/src/main/java/org/apache/druid/guice/JsonConfigurator.java:240

      String originalProperty,
      String property,
      Object value,
      Map<String, Object> targetMap
  )
  {
    int dotIndex = property.indexOf('.');
    // Always put property with name even if it is of form a.b. This will make sure the property is available for classes
    // where JsonProperty names are of the form a.b
    // Note:- this will cause more than required properties to be present in the jsonMap.
    targetMap.put(property, value);
    if (dotIndex < 0) {
      return;
    }
    if (dotIndex == 0) {
      throw new ProvisionException(StringUtils.format("Double dot in property: %s", originalProperty));
    }
    if (dotIndex == property.length() - 1) {
      throw new ProvisionException(StringUtils.format("Dot at the end of property: %s", originalProperty));
    }
    String nestedKey = property.substring(0, dotIndex);
    Object nested = targetMap.computeIfAbsent(nestedKey, k -> new HashMap<String, Object>());
    if (!(nested instanceof Map)) {
      // Clash is possible between properties, which are used to configure different objects: e. g.
      // druid.emitter=parametrized is used to configure Emitter class, and druid.emitter.parametrized.xxx=yyy is used
      // to configure ParametrizedUriEmitterConfig object. So skipping xxx=yyy key-value pair when configuring Emitter
      // doesn't make any difference. That is why we just log this situation, instead of throwing an exception.
      log.info(
          "Skipping property [%s]: one of it's prefixes [%s] is also used as a property key.",
          originalProperty,
          propertyPrefix
      );
      return;
    }
    Map<String, Object> nestedMap = (Map<String, Object>) nested;
    hieraricalPutValue(propertyPrefix, originalProperty, property.substring(dotIndex + 1), value, nestedMap);
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove the trailing dot from the listed property key so it ends with an actual key segment
  2. Delete the whole line if the property is no longer needed
  3. Regenerate or lint runtime.properties with a validator that rejects keys ending in '.'

Example fix

// before
druid.emitter.=parametrized
// after
druid.emitter=parametrized
Defensive patterns

Strategy: validation

Validate before calling

for (String key : props.stringPropertyNames()) {
  if (key.endsWith(".")) throw new IllegalArgumentException("Trailing dot in property key: " + key);
}

Try / catch

try { injector = Guice.createInjector(...); } catch (ProvisionException e) { if (e.getMessage().contains("Dot at the end")) log.error("Fix trailing-dot property key"); throw e; }

Prevention

When it happens

Trigger: hieraricalPutValue sees dotIndex == property.length() - 1, i.e. the property key string ends in '.' — triggered from configurate or recursively from hieraricalPutValue itself.

Common situations: A runtime.properties line like 'druid.emitter.=parametrized' or 'druid.storage.type.=' left after deleting the leaf key but not the trailing dot, often from manual editing or find/replace.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/ac33c028026e09ab. Report an issue: GitHub.