NationalSecurityAgency/ghidra · error · IOException

{} is not a valid certification authority

Error message

{} is not a valid certification authority

What it means

Thrown by checkCertAuthorityFile() when the path passed to --cafile resolves to something that is not a regular file (File.isFile() returns false: missing, a directory, or a broken symlink). BSim needs an actual CA file to copy into the data directory as root.crt for PostgreSQL client-cert verification.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java:849

			hostAuthentication = AUTHENTICATION_PASSWORD;
		}
		else if (hostMethod.equals(CERTIFICATE_METHOD)) {
			hostAuthentication = AUTHENTICATION_PKI;
		}
	}

	/**
	 * Make sure certificate authority needed for pki was provided by user, otherwise throw exception
	 * @throws IOException if the cert file is invalid
	 * @throws GeneralSecurityException if the cert file is not a valid certificate
	 */
	private void checkCertAuthorityFile() throws IOException, GeneralSecurityException {
		if (certAuthorityFile == null) {
			throw new IOException(
				"PKI authentication requested, but certificate authority file not provided");
		}
		if (!certAuthorityFile.isFile()) {
			throw new IOException(
				certAuthorityFile.getAbsolutePath() + " is not a valid certification authority");
		}
		if (!verifyPEMFormat(certAuthorityFile)) {
			throw new GeneralSecurityException(
				"File " + certAuthorityFile.getName() + " does not appear to be a certificate");
		}
	}

	/**
	 * Locate the PostgreSQL configuration and authentication files (postgresql.conf and pg_hba.conf)
	 * and recover the settings pertinent to BSimControl.  If the data directory has not been initialized yet,
	 * run PostgreSQL's init command to perform the initialization and then tailor the configuration
	 * based on BSimControl's command-line options and the Ghidra specific configuration options
	 * @throws IOException if the module data file cannot be retrieved
	 * @throws InterruptedException if the postgres command is interrupted
	 * @throws SAXException if tuneConfig fails
	 * @throws GeneralSecurityException if the cert file cannot be processed
	 */

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Check the path exists and is a file: `ls -l <cafile>` and confirm it is not a directory.
  2. Use an absolute path for --cafile to avoid working-directory ambiguity.
  3. Provision or regenerate the CA root certificate before running the command.
  4. Ensure the Ghidra process has read permission on the file.

Example fix

// before
bsim_ctl start --auth cert --cafile /etc/bsim
// after
bsim_ctl start --auth cert --cafile /etc/bsim/root.crt
Defensive patterns

Strategy: validation

Validate before calling

File ca = new File(caFilePath);
if (!ca.isFile()) {
    throw new IllegalArgumentException(
        "--cafile path is not a regular file: " + ca.getAbsolutePath());
}

Type guard

public boolean isReadableCertFile(File f) {
    return f != null && f.isFile() && f.canRead();
}

Try / catch

try {
    bsimControl.start(args);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().endsWith("is not a valid certification authority")) {
        throw new UserFacingException("CA file missing or not a file: " + caFilePath, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing `--cafile /path/that/does/not/exist` or pointing --cafile at a directory. The isFile() guard fires before any PEM content check.

Common situations: Typo in the CA path; relative path evaluated from the wrong working directory; CA file not yet generated/provisioned; pointing at the directory containing the cert instead of the cert file itself.

Understand the failure class

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/25faeca91a56de23. Report an issue: GitHub.