ansible/ansible · error · AnsibleParserError

An error occurred while trying to read the file {file_name!r

Error message

An error occurred while trying to read the file {file_name!r}.

What it means

In DataLoader._get_file_contents, any OSError from read_bytes() that is not FileNotFoundError (permission denied, is-a-directory, I/O error, name too long) is wrapped in AnsibleParserError 'An error occurred while trying to read the file {file_name!r}' with the original exception chained. The file exists but could not be read as bytes.

Source

Thrown at lib/ansible/parsing/dataloader.py:218

        :arg file_name: The name of the file to read.  If this is a relative
            path, it will be expanded relative to the basedir
        :raises AnsibleFileNotFound: if the file_name does not refer to a file
        :raises AnsibleParserError: if we were unable to read the file
        :return: Returns a byte string of the file contents
        """
        if not file_name or not isinstance(file_name, str):
            raise TypeError(f"Invalid filename {file_name!r}.")

        file_name = self.path_dwim(file_name)

        try:
            data = pathlib.Path(file_name).read_bytes()
        except FileNotFoundError as ex:
            # DTFIX-FUTURE: why not just let the builtin one fly?
            raise AnsibleFileNotFound("Unable to retrieve file contents.", file_name=file_name) from ex
        except OSError as ex:
            raise AnsibleParserError(f"An error occurred while trying to read the file {file_name!r}.") from ex

        data = Origin(path=file_name).tag(data)

        return self._decrypt_if_vault_data(data)

    def get_basedir(self) -> str:
        """ returns the current basedir """
        return self._basedir

    def set_basedir(self, basedir: str) -> None:
        """ sets the base directory, used to find files when a relative path is given """
        self._basedir = os.path.abspath(basedir)

    def path_dwim(self, given: str) -> str:
        """
        make relative paths work like folks expect.
        """

View on GitHub (pinned to 9cf16a4aca)

Solutions

  1. Inspect the resolved path with ls -la and confirm it is a regular file
  2. Fix permissions/ownership so the controller user can read it (chmod a+r or chown)
  3. Correct the path if it accidentally names a directory
  4. Remount/repair the filesystem if the underlying OSError is I/O related (see the chained 'from' exception)
Defensive patterns

Strategy: try-catch

Validate before calling

p = Path(loader.path_dwim(filename))
if not p.is_file():
    raise AnsibleError(f'{p} is not a regular file')
if not os.access(p, os.R_OK):
    raise AnsibleError(f'{p} is not readable by uid {os.getuid()}')

Try / catch

from ansible.errors import AnsibleParserError

try:
    data = loader.get_file_contents(filename)
except AnsibleParserError as e:
    cause = e.__cause__  # the original OSError: PermissionError, IsADirectoryError, ...
    if isinstance(cause, PermissionError):
        ...  # actionable message about modes/ownership
    raise

Prevention

When it happens

Trigger: Path exists but is a directory (IsADirectoryError); mode bits deny read to the controller user (PermissionError); file on an unavailable mount (OSError); path exceeds NAME_MAX.

Common situations: Ansible controller running as a user without read access to vault/vars files owned by root; playbook pointing a loader call at a directory; NFS/sshfs mounts dropped mid-run.

Related errors


AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15). Data as JSON: /api/errors/dc5b980d2cc614db. Report an issue: GitHub.