zaproxy/zaproxy · warning
Failed to read a callback entry, required prefix is empty.
Error message
Failed to read a callback entry, required prefix is empty.
What it means
OptionsParamApi.loadPersistentCallBacks requires both a URL and a prefix for each persistent callback entry. When the CALLBACK_PREFIX_KEY is absent or null for an entry that has a valid URL, the entry is skipped with this warning.
Source
Thrown at zap/src/main/java/org/zaproxy/zap/extension/api/OptionsParamApi.java:430
this.confirmRemovePermittedAddress = confirmRemove;
getConfig().setProperty(CONFIRM_REMOVE_ADDRESS, confirmRemovePermittedAddress);
}
private void loadPersistentCallBacks() {
List<HierarchicalConfiguration> fields =
((HierarchicalConfiguration) getConfig()).configurationsAt(CALLBACK_KEY);
persistentCallBacks = new HashMap<>(fields.size());
for (HierarchicalConfiguration sub : fields) {
String cbUrl = sub.getString(CALLBACK_URL_KEY, "");
if (cbUrl.isEmpty()) {
LOGGER.warn("Failed to read a callback entry, required url is empty.");
continue;
}
String cbPrefix = sub.getString(CALLBACK_PREFIX_KEY, null);
if (cbPrefix == null) {
LOGGER.warn("Failed to read a callback entry, required prefix is empty.");
continue;
}
persistentCallBacks.put(cbUrl, cbPrefix);
}
}
private void savePersistentCallBacks() {
((HierarchicalConfiguration) getConfig()).clearTree(CALLBACK_KEY);
int i = 0;
for (Entry<String, String> entry : persistentCallBacks.entrySet()) {
String elementBaseKey = CALLBACK_KEY + "(" + i + ").";
getConfig().setProperty(elementBaseKey + CALLBACK_URL_KEY, entry.getKey());
getConfig().setProperty(elementBaseKey + CALLBACK_PREFIX_KEY, entry.getValue());
i++;
}
try {
getConfig().save();View on GitHub (pinned to 9d1970a436)
Solutions
- Add the missing <prefix> value to the callback entry in the config file
- Remove the incomplete entry and re-register the persistent callback through its owning extension
- Inspect the extension that created the entry and ensure it persists both url and prefix
Example fix
// before (config.xml) <callback><url>https://example.com/cb</url></callback> // after <callback><url>https://example.com/cb</url><prefix>zap</prefix></callback>
Defensive patterns
Strategy: validation
Validate before calling
// before deploying config.xml // fail if any <callback> lacks a non-empty <prefix> // xmlstarlet sel -t -v "count(//callback[url and not(string(prefix))])" config.xml -> must be 0
Type guard
null
Try / catch
null
Prevention
- Always persist url AND prefix for persistent callbacks
- Let the owning extension write callback entries, not manual edits
- Validate config.xml against the expected OptionsParamApi schema
- Review ZAP upgrade notes for config format changes to callback entries
When it happens
Trigger: A config.xml <callback> entry contains a URL but no <prefix> child (or it is literally stored as null) — typically from manual edits or an incomplete save by the component registering callbacks.
Common situations: Hand-edited config files; older config formats migrated to a version that introduced required prefixes; scripts writing callback entries programmatically.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- session.method.script.dialog.error.text.notLoadedNorConfigur
- Failed to read a permitted address entry, required value is
- Failed to read a callback entry, required url is empty.
- Failed to load scan policy ({}):
- Found illegal value {} for alert threshold, using MEDIUM ins
AI-assisted analysis of zaproxy/zaproxy@9d1970a436 (2026-09-05).
Data as JSON: /api/errors/b84b6fa0525a4d06.
Report an issue: GitHub.