{"record":{"id":"22fd7ed324b28c14","repo":"ansible/ansible","slug":"could-not-read-password-file-pwd-file-r","errorCode":null,"errorMessage":"Could not read password file {pwd_file!r}.","messagePattern":"Could not read password file (.+?)\\.","errorType":"exception","errorClass":"AnsibleError","httpStatus":null,"severity":"error","filePath":"lib/ansible/cli/__init__.py","lineNumber":637,"sourceCode":"            cmd = [b_pwd_file]\n\n            try:\n                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n            except OSError as e:\n                raise AnsibleError(\"Problem occurred when trying to run the password script %s (%s).\"\n                                   \" If this is not a script, remove the executable bit from the file.\" % (pwd_file, e))\n\n            stdout, stderr = p.communicate()\n            if p.returncode != 0:\n                raise AnsibleError(\"The password script %s returned an error (rc=%s): %s\" % (pwd_file, p.returncode, to_text(stderr)))\n            secret = stdout\n\n        else:\n            try:\n                with open(b_pwd_file, \"rb\") as password_file:\n                    secret = password_file.read().strip()\n            except OSError as ex:\n                raise AnsibleError(f\"Could not read password file {pwd_file!r}.\") from ex\n\n        secret = secret.strip(b'\\r\\n')\n\n        if not secret:\n            raise AnsibleError('Empty password was provided from file (%s)' % pwd_file)\n\n        return to_text(secret)\n\n    @classmethod\n    def cli_executor(cls, args=None):\n        if args is None:\n            args = sys.argv\n\n        try:\n            display.debug(\"starting run\")\n\n            ansible_dir = Path(C.ANSIBLE_HOME).expanduser()\n            try:","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/cli/__init__.py#L619-L655","documentation":"Raised as AnsibleError (with the OSError chained via 'from') by CLI.get_password_from_file when the non-executable password file exists but cannot be opened/read: the open(b_pwd_file, 'rb') or .read() raises OSError. This covers permission problems, races where the file disappears between the exists() check and open(), and special files that fail to read.","triggerScenarios":"Password file with mode 600 owned by another user (run under a different account/sudo context); file on an NFS/FUSE mount with permission oddities; file deleted between check and read in concurrent automation; path is a directory.","commonSituations":"Running ansible via sudo or a CI service account while the vault file is owned by the invoking user with 600; files copied between hosts without chown; container mounts with numeric UID mismatch; multi-job workspaces where cleanup removes the file mid-run.","solutions":["Check ownership and mode: ls -l <file>; ensure the effective runtime user can read it (chmod 640 + proper group, or chown).","Confirm the runtime user context (whoami / id) matches the file's permissions, especially under sudo, systemd, or containers.","If the error is intermittent in automation, guard against concurrent deletion/recreation of the secret file (write atomically via rename).","Ensure the path is a regular file, not a directory or special device."],"exampleFix":"# before\n$ sudo -u ci-runner ansible-playbook site.yml --vault-password-file /home/dev/vault.txt\n# Could not read password file '/home/dev/vault.txt'. (PermissionError)\n\n# after\n$ chown ci-runner:ci-runner /home/dev/vault.txt   # or chmod 640 with shared group\n$ sudo -u ci-runner ansible-playbook site.yml --vault-password-file /home/dev/vault.txt","handlingStrategy":"validation","validationCode":"import os\n\ndef readable_regular_file(path: str) -> bool:\n    p = os.path.expanduser(path)\n    return os.path.isfile(p) and os.access(p, os.R_OK)\n\nif not readable_regular_file('vault.txt'):\n    raise PermissionError(f'{path} missing/unreadable for uid={os.getuid()}')","typeGuard":null,"tryCatchPattern":"from ansible.errors import AnsibleError\n\ntry:\\n    pwd = CLI.get_password_from_file(f)\\nexcept AnsibleError as e:\\n    if isinstance(e.__cause__, PermissionError):\\n        raise RuntimeError(f'{f} not readable by this user; fix ownership/mode') from e\\n    raise","preventionTips":["Store secrets 0600 owned by the exact account the ansible process runs as (watch sudo/systemd/CI service users).","In containers, align numeric UIDs of bind-mounted secret files or use mode 0644 with short-lived secrets.","Write secret files atomically (temp+rename) in automation to avoid read races."],"tags":["vault","password-file","permissions","oserror","ansible-cli","credentials"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}