zaproxy/zaproxy · warning · Exception
ascan.policy.warn.readonly
Error message
ascan.policy.warn.readonly
What it means
Read-only (built-in default) scan policies cannot be renamed; validateParam throws the localized 'ascan.policy.warn.readonly' message ('Policy is read-only') when the policy isReadOnly() and the name is left unchanged, blocking a save that would attempt to mutate it.
Source
Thrown at zap/src/main/java/org/zaproxy/zap/extension/ascan/PolicyAllCategoryPanel.java:572
if (newName.length() == 0) {
getPolicyName().requestFocusInWindow();
throw new Exception(Constant.messages.getString("ascan.policy.warn.noname"));
} else if (!extension.getPolicyManager().isLegalPolicyName(newName)) {
getPolicyName().requestFocusInWindow();
throw new Exception(
Constant.messages.getString(
"ascan.policy.warn.badname", PolicyManager.ILLEGAL_POLICY_NAME_CHRS));
} else if (!newName.equals(currentName)) {
// Name changed
if (extension.getPolicyManager().getAllPolicyNames().stream()
.anyMatch(newName::equalsIgnoreCase)) {
getPolicyName().requestFocusInWindow();
throw new Exception(Constant.messages.getString("ascan.policy.warn.exists"));
}
}
if (policy.isReadOnly() && newName.equals(currentName)) {
throw new Exception(Constant.messages.getString("ascan.policy.warn.readonly"));
}
}
@Override
public void saveParam(Object obj) throws Exception {
this.policy.setName(getPolicyName().getText());
if (locked != null) {
policy.setLocked(locked.isSelected());
}
}
/**
* This method initializes jScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {View on GitHub (pinned to 9d1970a436)
Solutions
- Duplicate the policy under a new name and modify the copy instead of the read-only default.
- Do not save read-only policies; cancel the dialog unless you actually renamed it.
- In code, check policy.isReadOnly() before invoking save/validation paths.
Example fix
// before if (panel.getPolicy().isReadOnly()) panel.saveParam(panel.getPolicy()); // throws // after if (!panel.getPolicy().isReadOnly()) panel.saveParam(panel.getPolicy());
Defensive patterns
Strategy: validation
Validate before calling
if (policy.isReadOnly()) { /* duplicate first */
ScanPolicy copy = new ScanPolicy(new File(dir, newName + ".policy"));
copy.setName(newName); policyManager.savePolicy(copy); return;
} Try / catch
try { panel.saveParam(obj); } catch (Exception e) { if (e.getMessage().startsWith("ascan.policy.warn.readonly")) { /* cancel or offer duplicate */ } } Prevention
- Check policy.isReadOnly() before enabling Save in UI or scripts
- Duplicate built-in policies before modifying them
- Never persist changes to default policies shipped with ZAP
When it happens
Trigger: Opening a built-in/default policy in the policy dialog and pressing OK (or attempting save) without changing the name - the dialog tries to save a read-only policy.
Common situations: Browsing the Default Policy tab and clicking OK; scripts or add-ons programmatically validating a read-only policy via the panel; attempting to modify default policies shipped with ZAP.
Related errors
- ascan.policy.warn.noname
- ascan.policy.warn.badname
- ascan.policy.warn.exists
- ALREADY_EXISTS
- Cannot change policy if the panel has not been defined as sw
AI-assisted analysis of zaproxy/zaproxy@9d1970a436 (2026-09-05).
Data as JSON: /api/errors/d78f18c4ed140547.
Report an issue: GitHub.