Skip to content
DevOps AI ToolKit
All guides
AI for Ansible By James Joyner IV · · 6 min read Last reviewed Jul 2026

Ansible Error: 'found a duplicate dict key' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Ansible's 'found a duplicate dict key' YAML error: remove the repeated mapping key, rename duplicated task keywords, or fix accidental copy-paste in vars.

  • #ansible
  • #troubleshooting
  • #automation
  • #yaml
Free toolkit

Stuck on this Ansible error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

YAML mappings must have unique keys. When the same key appears twice at one level, the second silently overrides the first — so Ansible’s parser raises a warning or error to stop you from losing data:

ERROR! While constructing a mapping from /etc/ansible/site.yml, line 8, column 3, found a duplicate dict key (state). Using last defined value only.

It usually surfaces after a copy-paste that repeats a keyword like state, name, when, or tags.

Symptoms

  • A play fails to load (or warns) pointing at a specific duplicated key.
  • A parameter you set “does not take effect” because a later duplicate wins.
  • The line/column in the message lands on the second occurrence.
ansible-playbook -i inventory.ini site.yml --syntax-check
ERROR! found a duplicate dict key (tags)

Common Root Causes

1. Repeated module parameter

Copy-paste leaves two state: or mode: keys under one module.

2. Repeated task keyword

Two when: or tags: on the same task — only the last applies.

3. Duplicate key in vars/inventory

The same variable defined twice in one vars: block or group_vars file.

4. Merged blocks after refactoring

Combining two tasks and forgetting to delete an overlapping key.

How to diagnose

Let YAML tooling point at the exact line:

yamllint site.yml
site.yml
  9:5   error   duplication of key "tags" in mapping  (key-duplicates)

Or with Python:

python3 - <<'PY'
import yaml
class Strict(yaml.SafeLoader): pass
def no_dup(loader, node, deep=False):
    seen=set()
    for k,_ in node.value:
        key=loader.construct_object(k, deep=deep)
        assert key not in seen, f"duplicate key: {key}"
        seen.add(key)
    return yaml.SafeLoader.construct_mapping(loader, node, deep)
Strict.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, no_dup)
yaml.load(open("site.yml"), Strict)
PY

Fixes

Remove the duplicate parameter

Wrong:

- name: Create dir
  ansible.builtin.file:
    path: /opt/app
    state: directory
    state: present        # duplicate — only this wins

Right:

- name: Create dir
  ansible.builtin.file:
    path: /opt/app
    state: directory

Merge repeated keywords intentionally

Two tags: become one list:

- name: Deploy
  ansible.builtin.copy:
    src: app.conf
    dest: /etc/app.conf
  tags:
    - config
    - deploy

De-duplicate vars

Combine repeated variable definitions into a single key with the intended value.

What to watch out for

  • The parser keeps the last value, so a duplicate can mask a bug where the wrong value silently wins — do not just delete one at random, confirm which value is correct.
  • Add key-duplicates to your yamllint config and run it in CI to catch this before a run.
  • Anchors/aliases and merge keys (<<) can reintroduce a key; check merged content too.
Free download · 368-page PDF

Fixed it? Get 500 Ansible & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Stuck on this? Start guided troubleshooting

Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.

Did this fix your issue?

Solved it a different way?

Share the fix that worked for you — reviewed, then published to help the next engineer.

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.