shwenzhang/AndResGuard · error · java.io.IOException

Failed to read : console closed

Error message

Failed to read ${description}: console closed

What it means

Thrown by PasswordRetriever.getPasswords when the password spec is 'pass:'-style? No — this fires for a console-backed spec: System.console() returned a Console but console.readPassword returned null, meaning the terminal/console was closed or unavailable so the secret (keystore or key password) could not be read interactively. It is a sentinel IOException wrapping an environment problem, not a wrong password.

Solutions

  1. Ensure the program is not run in an environment without an interactive console when pass:console password specs are used (e.g. run from a real terminal, not a detached/subprocess without a TTY)
  2. If console input is unavailable, supply the password via an alternative spec such as pass:<password>, file:<path>, or env:<variable>
  3. Check that the JVM's System.console() is non-null before relying on console-based password prompts
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at AndResGuard-core/src/main/java/apksigner/PasswordRetriever.java:288 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/ef5fde22922c9364. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/apksigner/PasswordRetriever.java:288

    //     -alias test
    //   generates a keystore and key which decrypt only with
    //   "\u0061\u0062\u00c2\u00a1\u00c3\u00a4\u00d1\u008e\u0031"
    // * keytool -genkey -v -keystore native.jks -keyalg RSA -keysize 2048 -validity 10000
    //     -alias test
    //   generates a keystore and key which decrypt only with
    //   "\u0061\u0062\u00a1\u00e4\u044e\u0031"

    assertNotClosed();
    if (spec.startsWith("pass:")) {
      char[] pwd = spec.substring("pass:".length()).toCharArray();
      return getPasswords(pwd);
    } else if (SPEC_STDIN.equals(spec)) {
      Console console = System.console();
      if (console != null) {
        // Reading from console
        char[] pwd = console.readPassword(description + ": ");
        if (pwd == null) {
          throw new IOException("Failed to read " + description + ": console closed");
        }
        return getPasswords(pwd);
      } else {
        // Console not available -- reading from redirected input
        System.out.println(description + ": ");
        byte[] encodedPwd = readEncodedPassword(System.in);
        if (encodedPwd.length == 0) {
          throw new IOException("Failed to read " + description + ": standard input closed");
        }
        // By default, textual input obtained via standard input is supposed to be decoded
        // using the in JVM default character encoding but we also try the console's
        // encoding just in case.
        return getPasswords(encodedPwd, Charset.defaultCharset(), CONSOLE_CHARSET);
      }
    } else if (spec.startsWith("file:")) {
      String name = spec.substring("file:".length());
      File file = new File(name).getCanonicalFile();
      InputStream in = mFileInputStreams.get(file);

View on GitHub (pinned to e4df245d82)