ansible/ansible · error · AnsibleOptionsError
stdin was empty, not encrypting
Error message
stdin was empty, not encrypting
What it means
AnsibleOptionsError raised by the stdin-reading branch of encrypt_string (active when '-' is an arg, --encrypt-string-stdin-name is set, or no args/--name given) when sys.stdin.read() returns ''. Like the empty-prompt case, encrypting zero bytes from a declared stdin source is rejected rather than emitting an empty encrypted string.
Source
Thrown at lib/ansible/cli/vault.py:335
else:
msg = "String to encrypt:"
prompt_response = display.prompt(msg, private=hide_input)
if prompt_response == '':
raise AnsibleOptionsError('The plaintext provided from the prompt was empty, not encrypting')
b_plaintext = to_bytes(prompt_response)
b_plaintext_list.append((b_plaintext, self.FROM_PROMPT, name))
# read from stdin
if self.encrypt_string_read_stdin:
if sys.stdout.isatty():
display.display("Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a newline)", stderr=True)
stdin_text = sys.stdin.read()
if stdin_text == '':
raise AnsibleOptionsError('stdin was empty, not encrypting')
if sys.stdout.isatty() and not stdin_text.endswith("\n"):
display.display("\n")
b_plaintext = to_bytes(stdin_text)
# defaults to None
name = context.CLIARGS['encrypt_string_stdin_name']
b_plaintext_list.append((b_plaintext, self.FROM_STDIN, name))
# use any leftover args as strings to encrypt
# Try to match args up to --name options
if context.CLIARGS.get('encrypt_string_names', False):
name_and_text_list = list(zip(context.CLIARGS['encrypt_string_names'], args))
# Some but not enough --name's to name each var
if len(args) > len(name_and_text_list):
# Trying to avoid ever showing the plaintext in the output, so this warning is vague to avoid that.View on GitHub (pinned to 9cf16a4aca)
Solutions
- Ensure the pipeline actually produces content: check the upstream command's output first
- Guard in scripts: test -n "$SECRET" && printf '%s' "$SECRET" | ansible-vault encrypt_string --stdin-name myvar
- If the value can legitimately be empty, decide explicitly — ansible-vault will not encrypt '' and you should skip the call
Example fix
# before
printf '%s' "$MY_TOKEN" | ansible-vault encrypt_string --stdin-name token # MY_TOKEN unset
# after
test -n "$MY_TOKEN" || { echo 'MY_TOKEN is empty' >&2; exit 1; }
printf '%s' "$MY_TOKEN" | ansible-vault encrypt_string --stdin-name token Defensive patterns
Strategy: validation
Validate before calling
import sys
data = sys.stdin.read()
if data == '':
raise SystemExit('stdin empty; upstream producer failed or secret unset')
# only then pipe into: ansible-vault encrypt_string --stdin-name NAME Prevention
- In pipelines, assert the secret variable is non-empty before piping
- Fail loudly when a secrets-manager lookup returns '' instead of piping it onward
When it happens
Trigger: `echo -n '' | ansible-vault encrypt_string --stdin-name myvar`, redirecting an empty file (`ansible-vault encrypt_string - < /dev/null`), or a pipeline upstream that produced no output.
Common situations: CI jobs where the secret variable is unset so the pipe carries an empty string; a previous command in the pipeline failed silently and emitted nothing.
Related errors
- The --prompt option is not supported if also reading input f
- '%s' is not a valid vault id. The character ';' is not allow
- At most one input file may be used with the --output option
- The plaintext provided from the prompt was empty, not encryp
- The plaintext provided from the command line args was empty,
AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15).
Data as JSON: /api/errors/4a9755dfdc7e504d.
Report an issue: GitHub.