apache/beam · error · java.lang.RuntimeException

Can't read parse private key

Error message

Can't read parse private key

What it means

KeyPairUtils.guessKeyEncryptionState reads a private key file and, if any IOException occurs while parsing the key's encryption state, wraps it in an uninformative RuntimeException('Can't read parse private key'). It is thrown only in the catch block after attempting to read the file contents, so it signals the key file could not be read or the input stream failed mid-parse.

Solutions

  1. Verify the private key file exists and is readable at the exact path on the machine executing the transform (Beam workers may differ from your local machine).
  2. Stage the key file with Beam's FileSystems/withBeamPipelineOptions (e.g. copy to a GCS path and use snowflake's keyFile staging) instead of relying on a local path.
  3. Convert the PKCS8 key to a plain unencrypted file (openssl pkcs8 -topk8 -nocrypt) if you don't need passphrase encryption, avoiding the encrypted-key parse path.
  4. Check file permissions (chmod 400/600) and that the path is absolute.

Example fix

// before
.withPrivateKey("/home/me/wrong-name.p8")
// after
.withPrivateKey("/etc/beam/keys/rsa_key.p8")  // absolute, existing, readable path
Defensive patterns

Strategy: validation

Validate before calling

java.nio.file.Path p = java.nio.file.Paths.get(keyPath);
if (!java.nio.file.Files.isRegularFile(p) || !java.nio.file.Files.isReadable(p)) {
  throw new IllegalStateException("Private key file missing or unreadable: " + p);
}

Prevention

When it happens

Trigger: Calling SnowflakeIO with a private key path/file whose underlying IOException occurs inside guessKeyEncryptionState (e.g. unreadable file, invalid path, stream closed) while the transform determines whether the key is ENCRYPTED_PRIVATE_KEY or UNENCRYPTED_PRIVATE_KEY.

Common situations: Private key file deleted or moved after config was written; wrong path or relative path resolved against a different working directory on a Beam worker; file permissions deny read on the runner node; key file is a directory or symlink to nothing.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/98bed4f36dc2b09d. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/KeyPairUtils.java:138

      if (pemObject == null) {
        // If it is not a PEM file then it is not possible to determine the encryption state
        return KeyEncryptionState.UNKNOWN;
      }
      if (ENCRYPTED_PRIVATE_KEY.equals(pemObject.getType())) {
        return KeyEncryptionState.ENCRYPT;
      } else if (UNENCRYPTED_PRIVATE_KEY.equals(pemObject.getType())) {
        return KeyEncryptionState.UNENCRYPTED;
      } else {
        throw new RuntimeException(
            "Invalid type of PEM file: "
                + pemObject.getType()
                + ". Supported types: "
                + ENCRYPTED_PRIVATE_KEY
                + ", "
                + UNENCRYPTED_PRIVATE_KEY);
      }
    } catch (IOException e) {
      throw new RuntimeException("Can't read parse private key");
    }
  }

  public static String readPrivateKeyFile(String privateKeyPath) {
    try {
      byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyPath));
      return new String(keyBytes, StandardCharsets.UTF_8);
    } catch (IOException e) {
      throw new RuntimeException("Can't read private key from provided path");
    }
  }
}

View on GitHub (pinned to 12126d8942)