elastic/elasticsearch · error · UserException

74

74

Error message

Please redirect binary output to a file instead

What it means

Thrown by `show` after the value failed to decode as UTF-8 (CharacterCodingException) AND the terminal has no redirectable output stream (getOutputStream() == null). Exits IO_ERROR (74). When an output stream IS available, the raw bytes are written there instead; this error only fires in headless contexts where binary content cannot be safely emitted.

Source

Thrown at distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/ShowKeyStoreCommand.java:82

                // This is not strictly true, but it's the best heuristic we have.
                // Without it we risk appending a newline to a binary file that happens to be valid UTF8
                final boolean isFileOutput = terminal.getOutputStream() != null;
                if (isFileOutput) {
                    terminal.print(Terminal.Verbosity.SILENT, text.toString());
                } else {
                    terminal.println(Terminal.Verbosity.SILENT, text);
                }
            } catch (CharacterCodingException e) {
                final OutputStream output = terminal.getOutputStream();
                if (output != null) {
                    bytes.writeTo(output);
                } else {
                    terminal.errorPrintln(Terminal.Verbosity.VERBOSE, e.toString());
                    terminal.errorPrintln(
                        "The value for the setting [" + settingName + "] is not a string and cannot be printed to the console"
                    );
                    throw new UserException(ExitCodes.IO_ERROR, "Please redirect binary output to a file instead");
                }
            }
        }
    }

}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Redirect to a file instead of printing to the console: pipe the command's stdout to a file.
  2. If you need the raw bytes programmatically, attach an OutputStream to the Terminal or read the keystore via the Java API directly.
  3. Confirm whether the setting was added with `add-file` (binary) vs `add-string` and adjust retrieval accordingly.

Example fix

// before
bin/elasticsearch-keystore show ssl.key   # binary value, no output stream
// after
bin/elasticsearch-keystore show ssl.key > /tmp/out.bin
Defensive patterns

Strategy: validation

Validate before calling

// Detect binary before printing: attempt UTF-8 decode and fall back to redirect
CharsetDecoder dec = StandardCharsets.UTF_8.newDecoder()
    .onMalformedInput(CodingErrorAction.REPORT)
    .onUnmappableCharacter(CodingErrorAction.REPORT);
boolean isText;
try { dec.decode(ByteBuffer.wrap(bytes)); isText = true; }
catch (CharacterCodingException e) { isText = false; }
if (!isText) {
    // ensure terminal.getOutputStream() != null, or write to a file directly
}

Try / catch

try {
    printValue(name);
} catch (UserException e) {
    if (e.exitCode == ExitCodes.IO_ERROR && e.getMessage().contains("binary")) {
        writeValueToFile(name, outFile);
    }
}

Prevention

When it happens

Trigger: Showing a binary-valued setting (e.g. an added-file certificate/key) in a Terminal that has no OutputStream attached; running show in a pure-logging harness that did not wire stdout.

Common situations: Treating a file-backed setting as a string; CI harnesses that capture only `terminal.println` text and not the byte stream.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/5a5e1351b0173742. Report an issue: GitHub.