NationalSecurityAgency/ghidra · error · IOException

Multiple settings for:

Error message

Multiple settings for: 

What it means

BSim's ServerConfig parser reads a server config file line by line, tracking recognized keys in a `keyValue` map. Each controlled setting key may be set at most once: when the parser encounters a key whose stored value is already non-empty, it throws IOException("Multiple settings for: " + key). This prevents ambiguous or contradictory configuration values.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ServerConfig.java:704

		String line;
		ConfigLine parse = new ConfigLine();

		try {
			for (;;) {
				line = reader.readLine();
				if (line == null) {
					break;		// End of file reached
				}
				if (line.length() != 0) {
					parse.parseUptoKey(line);
					if (parse.key == null) {
						continue;
					}
					String curval = keyValue.get(parse.key);		// Check if this is a key we want to find
					if (curval != null) {						// If this line is setting a value we control
						if (curval.length() != 0) {
							throw new IOException("Multiple settings for: " + parse.key);
						}
						parse.parseValue(line);		// Discard the original value, but preserve any comment
						if (parse.status == 1) {	// We have uncommented controlled key
							keyValue.put(parse.key, parse.value);
						}
					}
				}
			}
		}
		finally {
			reader.close();
		}
	}

	/**
	 * Read in all the entries of the connection file
	 * @param inFile the file to read in
	 * @throws IOException if the file cannot be read/parsed

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Read the trailing key name in the message and locate every occurrence of that directive in the config file.
  2. Delete the duplicate line(s), keeping a single canonical value.
  3. Restart the BSim server process so the parser re-reads the cleaned config.
  4. Add a pre-flight lint (grep for repeated keys) to CI for config files.

Example fix

# before
port       8080
database   bsim_primary
port       9090        # duplicate -- remove
# after
port       8080
database   bsim_primary
Defensive patterns

Strategy: validation

Validate before calling

// Before handing the file to ServerConfig, scan for duplicate controlled keys.
// (Adapt 'controlledKeys' to the set BSim recognizes: database, port, etc.)
Set<String> controlledKeys = Set.of("database", "port", "repository");
Map<String, Long> counts = new HashMap<>();
for (String line : Files.readAllLines(Path.of(confPath))) {
    String[] kv = line.trim().split("\\s+", 2);
    if (kv.length == 2 && controlledKeys.contains(kv[0]))
        counts.merge(kv[0], 1L, Long::sum);
}
Map<String, Long> dups = counts.entrySet().stream()
    .filter(e -> e.getValue() > 1)
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
if (!dups.isEmpty()) throw new IllegalStateException("Duplicate keys: " + dups);

Try / catch

try {
    ServerConfig.parse(confFile);
} catch (IOException e) {
    if (e.getMessage().startsWith("Multiple settings for:")) {
        // surface the duplicated key to the operator; do not retry
        throw new ConfigException("Fix duplicate directive: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Editing a BSim server .conf (e.g. bsimserver.conf) and listing the same controlled directive twice, such as two `database`, `port`, or `repository` lines. The parser reaches the second assignment, sees `curval` is already populated, and throws.

Common situations: Hand-merging config snippets; copy-pasting a template block without deleting the original; appending new config during a version upgrade and leaving the old line in place; trailing duplicate from a bad sed/awk edit.

Related errors


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