Cloud WAF/Docs 中文 EN
Cloud WAF is an enterprise Web protection management platform. Go + Gin REST API backend, Vue 3 SPA frontend, with the zcloud CLI for automation.

Error Code Reference

Business code = 0 means success; non-zero codes are module-specific. Every error response uses:
{ "code": <business_code>, "message": "<human readable>" }

This page lists all business error codes returned by Cloud WAF (mirroring pkg/errors/codes.go as the source of truth). Third-party integrators should branch on code and must not parse message text — the text is i18n / version dependent.

HTTP status vs business code

The platform uses a two-layer error model:

Layer Field Purpose
HTTP status code Protocol layer (4xx client error, 5xx server error); suitable for L4 LB / gateway logic
Business code (in JSON body) Application-level discriminator; the only reliable "what went wrong" signal

Conventions:

Common HTTP errors (not business codes)

Returned when a request never reaches business logic (validation, protocol, auth).

code HTTP Meaning Action
400 400 Bad request (JSON parse fail / missing required field) Fix payload, retry
401 401 Unauthenticated (missing/invalid/expired token) Re-login or rotate API key
403 403 Authenticated but lacks permission Request perm or use another account
404 404 Resource not found Check path / id
409 409 Conflict (e.g. duplicate create) Rename or delete the existing resource first
500 500 Internal server error Retry once; escalate to ops if persistent

Module code ranges

Module Range Notes
sys 1000–1999 User / role / OEM / session / API Key
guard 2000–2999 Domain / cert / policy / rules / IP set
node 3000–3999 Node / node group / IP / ACL policy
chart 4000–4999 Analytics chart query & export
alert 5000–5999 Alert task / record / contact
zdns 6000–6999 DNS domain / record
notify 7000–7999 Notify channel / template
report 8000–8999 Report task / file
assistant 9000–9999 AI assistant / session / KB / MCP tool
geoip 10000–10999 GeoIP lookup
channel 11000–11999 Channel partner onboarding

sys module (1000–1999)

Users & authentication (1001–1011)

code HTTP Meaning Action
1001 404 User not found Check username / id
1002 401 Invalid password Re-enter; repeated failures lock the account
1003 403 User locked Contact admin to unlock
1004 400 Invalid or expired captcha Refresh captcha and retry
1005 401 Session expired Re-login
1006 409 Username already exists Choose another name
1007 404 Role not found Check role id
1008 409 Role name already exists Choose another name
1009 403 Cannot delete this role (system built-in or in use) Detach references first
1010 400 Old password incorrect (during change-password) Re-enter old password
1011 403 Permission denied Request the corresponding perm

Settings & OEM (1012, 1020–1023)

code HTTP Meaning Action
1012 403 This setting is not modifiable via API (CLI / config file only) Use ops channel
1020 404 OEM not found Check OEM id
1021 409 OEM hostname already exists Use a different hostname
1022 403 Cannot delete the default OEM Default OEM is protected
1023 400 Invalid logo file (format / size) Upload a compliant image

Orders & plans (1030–1033, 1040)

code HTTP Meaning Action
1030 404 Order not found Check order id
1031 400 Invalid order status transition Follow the state machine
1032 404 Plan not found Check plan id
1033 409 Plan name already exists Rename
1040 404 Announcement not found Check announcement id

API Key sub-module (1050–1059)

code HTTP Meaning Retryable Re-issue needed
1050 401 API Key invalid / expired / revoked No Yes
1051 404 API Key not found or out of visible scope No N/A
1052 400 Requested scope exceeds the user's RBAC boundary No Yes (re-issue with narrower scope)
1053 403 API Key scope insufficient for the target endpoint No Maybe (re-issue with broader scope, or use the user-token channel)
1054 400 expires_in_days exceeds the upper bound of 365 No N/A
1055 400 API Key name is required No N/A
1056 403 Cross-OEM / cannot operate on another user's API Key No N/A

Scope matching: exact string equality, no wildcard expansion. Putting guard.* into a scope matches nothing — list all leaf perm keys explicitly when you want full module access.

guard module (2000–2999)

Domains & policies (2001–2010)

code HTTP Meaning Action
2001 404 Domain not found Check domain id
2002 409 Domain already exists Rename or delete the existing one
2003 404 Policy not found Check policy id
2004 409 Policy name already exists Rename
2005 404 Certificate not found Check cert id
2006 409 Certificate name already exists Rename
2007 400 Invalid certificate PEM Paste the full PEM (with BEGIN/END markers)
2008 409 Certificate already bound to this domain Skip the bind
2009 403 Policy is in use, cannot delete Detach domains first
2010 403 Domain has active nodes, cannot delete Disable the domain first

IP sets & rules (2011–2019)

code HTTP Meaning Action
2011 404 IP set not found Check set id
2012 409 IP set name already exists Rename
2013 409 IP already in the set Skip the add
2014 404 WAF rule group not found Check group id
2015 404 Forward rule not found Check forward id
2016 404 Schedule group not found Check schedule id
2017 403 Cannot delete the default schedule System-protected
2018 404 CC rule not found Check rule id
2019 404 ACL rule not found Check rule id

node module (3000–3999)

code HTTP Meaning Action
3001 404 Node not found Check node id
3002 409 Node name already exists Rename
3003 404 IP address not found Check IP id
3004 409 IP address already exists Skip
3005 404 Node group not found Check group id
3006 409 Node group name already exists Rename
3007 404 ACL policy not found Check policy id
3008 409 ACL policy name already exists Rename
3009 404 ACL rule not found Check rule id
3010 403 ACL policy still has rules, cannot delete Clear rules first

chart module (4000–4999)

code HTTP Meaning Action
4001 500 Chart query failed (PG / ES error) Retry once; escalate if persistent
4002 400 Invalid time range (stime > etime / span too wide) Narrow the range
4003 400 Invalid field (not in whitelist / typo) Verify field spelling
4004 500 Export failed Reduce data volume and retry
4005 429 Rate limited Back off and retry

alert module (5000–5999)

code HTTP Meaning Action
5001 404 Alert task not found Check task id
5002 409 Alert task name already exists Rename
5003 404 Alert record not found Check record id
5004 404 Alert contact not found Check contact id
5005 409 Alert contact already exists Skip
5006 404 Alert config not found Check config id
5007 400 Invalid alert type Use a valid enum value
5008 429 Alert in cooldown (debounce) Wait for cooldown to elapse
5009 429 Alert quota exceeded Raise the limit or wait for the next cycle
5010 500 Alert toggle failed Retry

zdns module (6000–6999)

code HTTP Meaning Action
6001 404 DNS domain not found Check domain id
6002 409 DNS domain already exists Rename
6003 404 DNS record not found Check record id
6004 404 DNS operation not found Check op id
6005 400 Invalid DNS record type Use A / AAAA / CNAME / MX / TXT …

notify module (7000–7999)

code HTTP Meaning Action
7001 404 Notify channel not found Check channel id
7002 409 Notify channel name already exists Rename
7003 404 Notify template not found Check template id
7004 409 Notify template name already exists Rename
7005 500 Notification send failed Verify channel connectivity, retry

report module (8000–8999)

code HTTP Meaning Action
8001 404 Report task not found Check task id
8002 409 Report task name already exists Rename
8003 404 Report file not found or expired Regenerate
8004 404 Report record not found Check record id
8005 500 Report generation failed Narrow time range / fields and retry

assistant module (9000–9999)

code HTTP Meaning Action
9001 404 AI session not found Check session id
9002 403 AI session is archived Unarchive or open a new session
9003 500 Message operation failed Retry
9004 404 MCP tool not found Check tool id
9005 409 Tool name already exists Rename
9006 404 Knowledge base not found Check kb id
9007 404 Document not found Check doc id
9008 404 AI config not found Check config id
9009 409 Knowledge base name already exists Rename
9010 500 Document indexing failed Verify document format and retry

geoip module (10000–10999)

code HTTP Meaning Action
10001 500 GeoIP query failed Retry once
10002 404 IP not in GeoIP database (private / unlisted) Query a public IP

channel module (11000–11999)

code HTTP Meaning Action
11001 404 Onboard flow not found Check onboard id
11002 410 Link expired Request a new link
11003 400 Invalid link token Request a new link
11004 409 Domain already exists Rename or delete the existing one
11005 500 Domain detect failed Verify DNS resolution and retry
11006 400 Invalid certificate Paste the full PEM
11007 400 Domains not ready for confirmation Wait for domain detect / cert install to complete

Cross-module conventions

Client handling pattern

# Python pseudo-code: branch on business code, not HTTP status
import requests
from time import sleep

resp = requests.get(api_url, headers={"Authorization": f"ApiKey {key}"})
body = resp.json()
code = body.get("code", -1)

if code == 0:
    return body["data"]
elif code == 1050:
    raise Exception("API Key invalid, please re-issue")
elif code == 1052:
    raise Exception(f"scope exceeded: {body['message']}")
elif code in (4005, 5008, 5009):
    sleep(int(resp.headers.get("Retry-After", "60")))
    return retry()
elif code >= 5000 and resp.status_code >= 500:
    return exponential_backoff_retry()
else:
    raise Exception(f"business error {code}: {body['message']}")

Always branch on code. Never parse message text — it changes with i18n and version.