apache/seatunnel · error · InvalidConfigurationException

Duplicate ' ' definition found in the configuration.

Error message

Duplicate '${nodeName}' definition found in the configuration.

What it means

YamlSeaTunnelDomConfigProcessor.buildConfig walks the config DOM and tracks seen node names; a key that appears twice at a level where duplicates are not allowed (not in canOccurMultipleTimes) triggers InvalidConfigurationException naming the duplicated key.

Solutions

  1. Find the duplicated key from the message and merge the two blocks into one.
  2. Merge configs key-wise programmatically instead of concatenating text.
  3. Verify post-merge that each top-level key occurs only once unless allowed multiple times.

Example fix

# before
slot-service:
  dynamic-slot: true
slot-service:
  slot-num: 5
# after
slot-service:
  dynamic-slot: true
  slot-num: 5
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (Object key : topLevelKeys(cfgText)) {
    if (!seen.add(key)) throw new IllegalStateException("duplicate top-level key: " + key);
}

Try / catch

try {
    processor.buildConfig(rootNode);
} catch (InvalidConfigurationException e) {
    LOG.severe("Fix duplicated key in config: " + e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: buildConfig(rootNode) on a parsed seatunnel.yaml containing the same section/key twice at the same level (e.g. two merged documents, duplicated slot-service blocks).

Common situations: Config merge that concatenated two full documents instead of merging keys; copy-paste adding a second copy of a section; tooling appending a key that already exists.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/249017f9fb615df9. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelDomConfigProcessor.java:77

import static com.hazelcast.internal.config.DomConfigHelper.getIntegerValue;

/** Builds {@link SeaTunnelConfig} from the YAML DOM tree used by the engine startup path. */
public class YamlSeaTunnelDomConfigProcessor extends AbstractDomConfigProcessor {
    private static final ILogger LOGGER = Logger.getLogger(YamlSeaTunnelDomConfigProcessor.class);

    private final SeaTunnelConfig config;

    YamlSeaTunnelDomConfigProcessor(boolean domLevel3, SeaTunnelConfig config) {
        super(domLevel3);
        this.config = config;
    }

    @Override
    public void buildConfig(Node rootNode) {
        for (Node node : childElements(rootNode)) {
            String nodeName = cleanNodeName(node);
            if (occurrenceSet.contains(nodeName)) {
                throw new InvalidConfigurationException(
                        "Duplicate '" + nodeName + "' definition found in the configuration.");
            }
            if (handleNode(node, nodeName)) {
                continue;
            }
            if (!SeaTunnelConfigSections.canOccurMultipleTimes(nodeName)) {
                occurrenceSet.add(nodeName);
            }
        }
    }

    private boolean handleNode(Node node, String name) {
        if (SeaTunnelConfigSections.ENGINE.isEqual(name)) {
            parseEngineConfig(node, config);
        } else {
            return true;
        }
        return false;

View on GitHub (pinned to cf67b549a7)