ansible/ansible · error · ValueError
MD5 not available. Possibly running in FIPS mode
Error message
MD5 not available. Possibly running in FIPS mode
What it means
Raised by AnsibleModule.md5() in ansible.module_utils.basic when the 'md5' hash algorithm is absent from AVAILABLE_HASH_ALGORITHMS. This almost always means the managed host's Python/OpenSSL is running in FIPS-140-2 mode, where OpenSSL refuses to register MD5. The method's own docstring states it will not work on FIPS-compliant systems and that most callers should use sha256/sha1 instead.
Source
Thrown at lib/ansible/module_utils/basic.py:1585
while block:
digest_method.update(block)
block = infile.read(blocksize)
infile.close()
return digest_method.hexdigest()
def md5(self, filename):
""" Return MD5 hex digest of local file using digest_from_file().
Do not use this function unless you have no other choice for:
1) Optional backwards compatibility
2) Compatibility with a third party protocol
This function will not work on systems complying with FIPS-140-2.
Most uses of this function can use the module.sha1 function instead.
"""
if 'md5' not in AVAILABLE_HASH_ALGORITHMS:
raise ValueError('MD5 not available. Possibly running in FIPS mode')
return self.digest_from_file(filename, 'md5')
def sha1(self, filename):
""" Return SHA1 hex digest of local file using digest_from_file(). """
return self.digest_from_file(filename, 'sha1')
def sha256(self, filename):
""" Return SHA-256 hex digest of local file using digest_from_file(). """
return self.digest_from_file(filename, 'sha256')
def backup_local(self, fn):
"""make a date-marked backup of the specified file, return True or False on success or failure"""
backupdest = ''
if os.path.exists(fn):
# backups named basename.PID.YYYY-MM-DD@HH:MM:SS~
ext = time.strftime("%Y-%m-%d@%H:%M:%S~", time.localtime(time.time()))
backupdest = '%s.%s.%s' % (fn, os.getpid(), ext)View on GitHub (pinned to 9cf16a4aca)
Solutions
- Switch to module.sha256(filename) or module.checksum_s('sha256') for local file digests
- For copy/get_url style tasks, pass checksum with a stronger algorithm, e.g. checksum: sha256:...
- If a third-party protocol mandates MD5, run the task with FIPS disabled (remove fips=1 and reboot) or use a Python/OpenSSL build with a non-FIPS MD5
- If you maintain the module, gate the MD5 path: offer an algorithm option and fall back to sha256 when 'md5' not in AVAILABLE_HASH_ALGORITHMS
Example fix
# before
checksum = module.md5(dest_file)
# after
if 'md5' in AVAILABLE_HASH_ALGORITHMS:
checksum = module.md5(dest_file)
else:
checksum = module.sha256(dest_file) Defensive patterns
Strategy: validation
Validate before calling
from ansible.module_utils.basic import AVAILABLE_HASH_ALGORITHMS
if 'md5' not in AVAILABLE_HASH_ALGORITHMS:
# FIPS host: pick a strong digest before calling module.md5
digest = module.sha256(path)
else:
digest = module.md5(path) Type guard
def md5_available() -> bool:
return 'md5' in AVAILABLE_HASH_ALGORITHMS Try / catch
try:
digest = module.md5(path)
except ValueError as e:
if 'FIPS' in str(e):
digest = module.sha256(path)
else:
raise Prevention
- Default to sha256 for local digests; reserve MD5 for third-party protocols that mandate it
- Prefer checksum: sha256:... on copy/get_url tasks instead of relying on module defaults
- Document FIPS incompatibility in module docs if MD5 is required
When it happens
Trigger: Calling module.md5('/path/to/file') (directly or via a module feature that compares MD5 checksums, e.g. copy/get_url with checksum=md5:...) on a host where hashlib does not expose md5 because FIPS enforcement (OPENSSL_FORCEFIPS_MODE=1, a FIPS kernel, or a FIPS-configured OpenSSL) is active.
Common situations: RHEL/CentOS hosts in FIPS mode (fips=1 kernel cmdline), government or compliance-hardened environments, and modules that still default to MD5 for backward compatibility with third-party protocols that require MD5.
Related errors
- Checksum mismatch for '%s' inside collection at '%s'
- Could not make backup of {fn!r} to {backupdest!r}.
- The destination directory {os.path.dirname(dest)!r} is not w
- Unable to make {src!r} into to {dest!r}, failed final rename
- Failed to replace {dest!r} with {src!r}.
AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15).
Data as JSON: /api/errors/5c63e7fde8d6a9d5.
Report an issue: GitHub.