Fixing Jinja2 'template error while templating string' in Ansible

beginner๐Ÿ”ง Ansible2026-04-21| Ansible 2.9+, Python 3.x, Linux/macOS

Error Message

AnsibleError: template error while templating string: expected token ':', got '}'. String: {{ myvar }
#ansible#jinja2#template#variable#syntax

TL;DR: The Quick Fix

This error is almost always caused by a syntax typo in your Jinja2 expression. The most common culprit is a missing closing brace } or a malformed inline if/else statement.

Check the line mentioned in the error and ensure your variable looks like this:

# Wrong
msg: "{{ myvar }"

# Right
msg: "{{ myvar }}"

If you are using an inline conditional, ensure you have both if and else:

# Wrong (missing else)
msg: "{{ 'active' if enabled }}"

# Right
msg: "{{ 'active' if enabled else 'inactive' }}"

The Root Cause

Ansible uses the Jinja2 templating engine to evaluate everything inside {{ ... }}. When you see expected token ':', got '}', it means the Jinja2 parser was expecting a specific character to follow your variable or expression, but it hit a closing brace (or the end of the string) instead.

The parser gets "confused" depending on the context. For example, if it thinks you are starting a dictionary mapping or a ternary-style operation, it looks for a colon :. If you provide a single } instead of the expected }}, the parser fails because the expression is syntactically incomplete.

Common Scenarios and Fixes

1. The Missing Brace (The Typo)

This is the most frequent cause. You start a variable with {{ but only close it with a single }.

# Fails with: expected token ':', got '}'
- name: Print a variable
  ansible.builtin.debug:
    msg: "The value is {{ web_server_port }"

The Fix: Always ensure you have matching pairs of double braces.

- name: Print a variable
  ansible.builtin.debug:
    msg: "The value is {{ web_server_port }}"

2. Incomplete Inline Ternary Expressions

Jinja2 supports value_if_true if condition else value_if_false. Unlike some other languages, the else part is mandatory in Jinja2 expressions when used inside {{ ... }}.

# Fails
- name: Set status
  ansible.builtin.set_fact:
    app_status: "{{ 'running' if service_up }}"

The Fix: Add the else clause.

- name: Set status
  ansible.builtin.set_fact:
    app_status: "{{ 'running' if service_up else 'stopped' }}"

3. Improper Quoting in YAML

Sometimes the YAML parser and the Jinja2 parser clash. If your string starts with {{, YAML requires the entire line to be quoted. If you miss the quotes or use them incorrectly, the Jinja2 string passed to the engine might be truncated or mangled.

# Might cause issues
- name: Incorrect quoting
  shell: echo {{ my_var }

The Fix: Always quote your Jinja2 expressions when they are the start of a value.

- name: Correct quoting
  shell: "echo {{ my_var }}"

4. Dictionary Syntax Inside Expressions

If you are trying to access a dictionary key or define a dictionary on the fly, a missing colon or quote will trigger this error.

# Fails if you forget the colon in a dict
- name: Buggy dict access
  ansible.builtin.set_fact:
    config: "{{ {'port' 8080} }}"  # Missing colon after 'port'

Verification Steps

To confirm the fix, run your playbook with the syntax check flag. This is faster than running the whole deployment.

ansible-playbook my_playbook.yml --syntax-check

If the syntax check passes, use the debug module to verify the expression renders correctly:

- name: Debugging the fix
  ansible.builtin.debug:
    msg: "Variable is: {{ myvar }}"

Pro-Tips for Prevention

  • Use an IDE extension: VS Code with the "Ansible" or "Jinja2" extension will highlight mismatched braces in red.
  • Spaces matter for readability: Use {{ variable }} instead of {{variable}}. It makes it much easier to spot a missing brace at the end.
  • Linter: Run ansible-lint. It often catches these low-level syntax errors before you even try to run the code.

Related Error Notes