NationalSecurityAgency/ghidra · error · IllegalArgumentException

Unable to infer BSim URL from: {}

Error message

Unable to infer BSim URL from: {}

What it means

deriveBSimURL() first tries to parse the URL and check if its protocol is a native BSim protocol (postgresql/https/elastic/file). If not, it checks GhidraURL.isServerRepositoryURL(). If that also returns false, IllegalArgumentException is thrown — the URL is neither a direct BSim URL nor a Ghidra server repository URL from which a BSim URL can be derived.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimClientFactory.java:89

	 * Alternately -url- can reference a ghidra server, as indicated by the "ghidra" protocol.
	 *    In this case the true BSim URL is derived from ghidra URL in some way
	 * @param urlString is the "related" URL
	 * @return the root BSim URL
	 * @throws MalformedURLException if the given URL string cannot be parsed
	 * @throws URISyntaxException if the given URL string cannot be parsed
	 * @throws IllegalArgumentException if local ghidra URL is specified
	 */
	public static URL deriveBSimURL(String urlString)
			throws IllegalArgumentException, MalformedURLException, URISyntaxException {
		URL url = new URI(urlString).toURL();	// URL used only for parsing purposes
		String protocol = url.getProtocol();
		if ("postgresql".equals(protocol) || "https".equals(protocol) ||
			"elastic".equals(protocol) || "file".equals(protocol)) {
			checkBSimServerURL(url);
			return url; // URL already corresponds to BSim server protocol
		}
		if (!GhidraURL.isServerRepositoryURL(url)) {
			throw new IllegalArgumentException("Unable to infer BSim URL from: " + url);
		}
		String path = url.getPath();							// Get the full path of the URL
		if (path == null || path.length() == 0 || path.equals("/")) {		// There must always be some kind of path, so we can derive the repository
			throw new MalformedURLException("URL is missing a repository path");
		}
		int endrepos = path.indexOf('/', 1);	// Find the end of the first level of the path
		String repositoryURL;
		if (url.getProtocol().equals(GhidraURL.PROTOCOL)) {	// Is this a ghidra URL
			// TODO: we could set things up so that a ghidra server could be queried for its associated BSim server
			// "ghidra://host/repo?service=bsim"
			// String repositoryURL = "ghidra://" + ghidraURL.getAuthority() + "?service=bsim";

			// Currently, all we do is assume that the BSim server is a PostgreSQL server
			// on the same host and with the same repo name as the ghidra server
			repositoryURL = "postgresql://" + url.getHost();		// Just use the hostname
		}
		else {
			// For all other URL forms, we assume we are being handed the protocol and hostname (authority)

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Prefix the URL with a valid BSim protocol: postgresql://, https://, elastic://, or file:/.
  2. If referencing a Ghidra server repository, use the ghidra:// protocol format so isServerRepositoryURL returns true.
  3. Validate the URL string is well-formed before passing it to deriveBSimURL.
  4. Check for typos in the scheme or missing '://' separator.

Example fix

// before
URL url = BSimClientFactory.deriveBSimURL("myhost:5432/bsimdb"); // no protocol
//
// after
URL url = BSimClientFactory.deriveBSimURL("postgresql://myhost:5432/bsimdb");
Defensive patterns

Strategy: validation

Validate before calling

URL test = new URI(urlString).toURL();
String proto = test.getProtocol();
boolean isBSim = Set.of("postgresql", "https", "elastic", "file").contains(proto);
boolean isGhidraRepo = GhidraURL.isServerRepositoryURL(test);
if (!isBSim && !isGhidraRepo) {
    // Inform user: URL must be a BSim protocol or a Ghidra server repository URL
}

Try / catch

try {
    BSimClientFactory.deriveBSimURL(urlString);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unable to infer BSim URL")) {
        // prompt user for a valid BSim or ghidra:// URL
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling deriveBSimURL(urlString) where the URL protocol is not a BSim protocol AND GhidraURL.isServerRepositoryURL(url) returns false. The string doesn't resolve to any known BSim or Ghidra server format.

Common situations: User provides a bare hostname without protocol; user provides a local filesystem path without 'file:' prefix; user provides an http URL (not in the BSim protocol set); malformed URL string; user provides a URL with an unrecognized scheme (e.g., ftp, ssh).

Related errors


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