NationalSecurityAgency/ghidra · error · MalformedURLException

URL is missing a repository path

Error message

URL is missing a repository path

What it means

Inside deriveBSimURL(), after confirming the URL is a Ghidra server repository URL, it checks the path. If the path is null, empty, or '/' it throws MalformedURLException because deriving the BSim repository name requires at least one path level (the repository name). Without a path, there's nothing to map to a BSim database name.

Source

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

	 * @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)
			// explicitly. We keep them for the final BSim URL
			repositoryURL = url.getProtocol() + "://" + url.getAuthority();
		}
		// Attach the first level of the path, which indicates the repository

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Include the repository name in the ghidra URL path: 'ghidra://myhost/repositoryName'.
  2. Verify the ghidra URL construction includes the repository path segment.
  3. Check that the configuration source providing the URL includes the repository name, not just the host.

Example fix

// before
URL url = BSimClientFactory.deriveBSimURL("ghidra://myhost/"); // no repo path
//
// after
URL url = BSimClientFactory.deriveBSimURL("ghidra://myhost/MyRepository");
Defensive patterns

Strategy: validation

Validate before calling

URL test = new URI(urlString).toURL();
if (GhidraURL.isServerRepositoryURL(test)) {
    String path = test.getPath();
    if (path == null || path.isEmpty() || path.equals("/")) {
        // ghidra URL must include the repository name in the path
        throw new IllegalArgumentException(
            "Ghidra URL must include a repository name: ghidra://host/repository");
    }
}

Try / catch

try {
    BSimClientFactory.deriveBSimURL(urlString);
} catch (MalformedURLException e) {
    if (e.getMessage().contains("missing a repository path")) {
        // prompt user to include the repository name
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling deriveBSimURL(urlString) where the URL passes isServerRepositoryURL (ghidra:// scheme) but getPath() is null/empty/'/'. The ghidra URL has no repository path component.

Common situations: A ghidra:// URL pointing only to a server root without a repository name (e.g., 'ghidra://myhost/'); malformed ghidra URL construction that dropped the path; URL constructed from host-only configuration.

Related errors


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