apache/pulsar · error · IllegalArgumentException

Field ${name} must be a Map

Error message

Field ${name} must be a Map

What it means

The map-validator NestableFieldValidator throws IllegalArgumentException when the field is non-null but not a java.util.Map, indicating a map-typed config field was given some other object (list, string, etc.).

Source

Thrown at pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ConfigValidationUtils.java:140

            @SuppressWarnings("unchecked")
            @Override
            public void validateField(String pd, String name, Object field)
                    throws IllegalArgumentException {
                if (field == null) {
                    if (notNull) {
                        throw new IllegalArgumentException("Field " + name + " must not be null");
                    } else {
                        return;
                    }
                }
                if (field instanceof Map) {
                    for (Map.Entry<Object, Object> entry : ((Map<Object, Object>) field).entrySet()) {
                        key.validateField("Each key of the map ", name, entry.getKey());
                        val.validateField("Each value in the map ", name, entry.getValue());
                    }
                    return;
                }
                throw new IllegalArgumentException(
                        "Field " + name + " must be a Map");
            }
        };
    }

    /**
     * Declares methods for validating configuration values.
     */
    public interface FieldValidator {
        /**
         * Validates the given field.
         *
         * @param name  the name of the field.
         * @param field The field to be validated.
         * @throws IllegalArgumentException if the field fails validation.
         */
        void validateField(String name, Object field) throws IllegalArgumentException;
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Rewrite the value as a mapping (YAML 'key: value' pairs / JSON object)
  2. Fix programmatic construction to assign a Map type matching the field declaration
  3. Check the validator's declared key/value validators to ensure entries conform once it is a Map

Example fix

# before (list instead of map)
options:
  - a=1
# after
options:
  a: "1"
Defensive patterns

Strategy: type-guard

Validate before calling

// before validateConfig
Object options = conf.get("options");
if (!(options instanceof java.util.Map)) throw new IllegalStateException("options must be a key/value map");

Type guard

static boolean isMap(Object o) { return o instanceof java.util.Map; }

Try / catch

try {
    ConfigValidation.validateConfig(conf);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Map field given non-map value: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: A map-typed config property assigned a List, String, or other non-Map value before ConfigValidation runs validateField.

Common situations: YAML written as a dash list where a mapping (key: value) is required; JSON array supplied for an object field; programmatic assignment of a List where Map<String,String> is declared.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/6d42f2ecfbf5a881. Report an issue: GitHub.