shwenzhang/AndResGuard · error · java.io.IOException

Failed to read : environment variable not specified

Error message

Failed to read ${description}: environment variable ${value} not specified

What it means

Thrown by PasswordRetriever.getPasswords for an 'env:<VAR>' password spec: the named environment variable is unset (value == null). The tool expected the secret to be exported in the environment but found nothing, so it cannot supply the requested password. This is a configuration/spec mismatch, not a wrong-password error.

Solutions

  1. Set the environment variable named by the env:<name> password spec before running the tool (e.g. export KEYSTORE_PASSWORD=...)
  2. Pass the variable through to the subprocess if the tool is invoked from a script or CI where the environment is not inherited
  3. Alternatively use a different password spec: pass:<password>, file:<path>, or console
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at AndResGuard-core/src/main/java/apksigner/PasswordRetriever.java:322 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/254612ccddfcccfc. Report an issue: GitHub.

Appendix: source

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

      String name = spec.substring("file:".length());
      File file = new File(name).getCanonicalFile();
      InputStream in = mFileInputStreams.get(file);
      if (in == null) {
        in = new FileInputStream(file);
        mFileInputStreams.put(file, in);
      }
      byte[] encodedPwd = readEncodedPassword(in);
      if (encodedPwd.length == 0) {
        throw new IOException("Failed to read " + description + " : end of file reached in " + file);
      }
      // By default, textual input from files is supposed to be treated as encoded using JVM's
      // default character encoding.
      return getPasswords(encodedPwd, Charset.defaultCharset());
    } else if (spec.startsWith("env:")) {
      String name = spec.substring("env:".length());
      String value = System.getenv(name);
      if (value == null) {
        throw new IOException("Failed to read " + description + ": environment variable " + value + " not specified");
      }
      return getPasswords(value.toCharArray());
    } else {
      throw new IOException("Unsupported password spec for " + description + ": " + spec);
    }
  }

  private void assertNotClosed() {
    if (mClosed) {
      throw new IllegalStateException("Closed");
    }
  }

  @Override
  public void close() {
    for (InputStream in : mFileInputStreams.values()) {
      try {
        in.close();

View on GitHub (pinned to e4df245d82)