#85283·ansible

Module blockinfile doesn't respect line endings that differ from os.linesep

Author: je2555Created Jun 9, 2025Updated Sep 10, 2026
Labelsmodulebughas_prneeds_verifiedaffects_2.18

Summary

When a file on a UNIX system using UNIX LF line endings is updated to have Windows CRLF line endings, blockinfile is no longer idempotent, does not detect the existing block and writes a new block with UNIX LF that does not match the rest of the file.

Issue Type

Bug Report

Component Name

blockinfile

Ansible Version

$ ansible --version
ansible [core 2.18.6]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /root/scripts/cron/ansible/lib64/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = bin/ansible
  python version = 3.11.11 (main, Dec 12 2024, 09:11:52) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] (/root/scripts/cron/ansible/bin/python3.11)
  jinja version = 3.1.3
  libyaml = True

Configuration

# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
CONFIG_FILE() = None

GALAXY_SERVERS:

OS / Environment

RHEL 8 (AlmaLinux 8)

Steps to Reproduce

ansible -m file -a "path=/tmp/block.test state=touch" localhost
ansible -m blockinfile -a "path=/tmp/block.test block=blocktext" localhost
ansible -m replace -a "path=/tmp/block.test regexp='^(.*)$' replace='\1\r'" localhost
ansible -m blockinfile -a "path=/tmp/block.test block=blocktext" localhost

Expected Results

The second time running blockinfile should detect the existing block and not modify the file, reporting OK - no change.

I would also accept detecting the existing block and modifying the existing block to change the line endings back to UNIX LF if you prefer.

In either case, relying on os.linesep is not sufficiently robust because not all files on an OS use the correct line endings - especially in a multi-user environment. In our case, these files that use blockinfile to manage certain configuration settings are also modified by developers outside our control using windows tools which automatically change the line endings throughout the file. Not ideal I know, but it's the environment we're working with.

The blockinfile module should detect the block using markers no matter what line endings are in use.

Actual Results

[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | CHANGED => {
    "changed": true,
    "msg": "Block inserted"
}

Code of Conduct

  • I agree to follow the Ansible Code of Conduct