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

  1. Add the missing <prefix> value to the callback entry in the config file
  2. Remove the incomplete entry and re-register the persistent callback through its owning extension
  3. 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

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


AI-assisted analysis of zaproxy/zaproxy@9d1970a436 (2026-09-05). Data as JSON: /api/errors/b84b6fa0525a4d06. Report an issue: GitHub.