Errors
API errors
A complete numeric error-code catalog is not published. Do not invent codes. Use the shapes and status codes actually returned by handlers.
Envelopes
AUTH_ERR
Used by AuthHandler and many older c.JSON(..., gin.H{"error": ...}) paths.
{"error": "Invalid credentials"}Some 2FA login failures add requires_2fa:
{"error": "Two-factor authentication code required", "requires_2fa": true}V1ERR (`utils.V1ErrorResponse`)
{
"success": false,
"error": "Invalid request format",
"message": "Invalid request format",
"code": "BAD_REQUEST"
}Helper codes from response_helper.go:
Scroll sideways to see the full table. Use the arrow keys when focused.
| HTTP | code | Helper |
|---|---|---|
| 400 | BAD_REQUEST | RespondBadRequest |
| 401 | UNAUTHORIZED | RespondUnauthorized |
| 403 | FORBIDDEN | RespondForbidden |
| 404 | NOT_FOUND | RespondNotFound |
| 409 | CONFLICT | RespondConflict |
| 500 | INTERNAL_ERROR | RespondInternalError |
Handlers may pass a different code string into RespondError (example: license import PAYLOAD_TOO_LARGE at 413).
V1OK (`utils.V1SuccessResponse`)
{
"success": true,
"message": "license status loaded",
"data": {}
}data is omitted when the helper is called with nil.
License 403 (Enterprise)
licensegate.Gate writes licensing.LicenseErrorResponse on denied entitlement:
{
"success": false,
"code": "LICENSE_FEATURE_NOT_ENTITLED",
"message": "<gate message>",
"license": {
"state": "<license state>",
"edition": "<edition>",
"feature": null,
"limit": null,
"operation": "<operation>",
"remediation_hint": "<hint>"
}
}license is LicenseErrorDetails. Optional fields include sku, channel, required_channel, required_edition, current_usage, allowed_limit. Do not publish SKU names as a customer price list.
Observed bounded codes in Manager metrics (not a complete public catalog): LICENSE_LIMIT_EXCEEDED, LICENSE_FEATURE_NOT_ENTITLED, LICENSE_RESTRICTED_WRITE_DENIED, LICENSE_CLUSTER_JOIN_DENIED, LICENSE_AGENT_REGISTRATION_DENIED, plus updater-channel codes that belong to the in-product updater (not a production upgrade path).
When the license service itself is missing, license routes return 503:
{
"success": false,
"error": "license service unavailable",
"message": "license service unavailable",
"code": "LICENSE_SERVICE_UNAVAILABLE"
}Community agent limit 403
Community only (Zwall_Community AgentHandler.respondCommunityAgentLimit). Fired on registration-style enroll, web create, and pre-register when CountAgents >= 3.
{
"success": false,
"error": "COMMUNITY_AGENT_LIMIT_REACHED",
"code": "COMMUNITY_AGENT_LIMIT_REACHED",
"message": "ZWall Community supports up to 3 agents",
"limit": 3,
"current_agents": 3
}Enterprise uses license gates instead of this Community constant.
HTTP status usage (operator)
Scroll sideways to see the full table. Use the arrow keys when focused.
| Status | Typical meaning |
|---|---|
| 200 | Success, including idempotent security-log replay and logout with no credentials |
| 201 | Created (rules, pre-register, GeoIP rules, some logs/notifications) |
| 400 | Bind/validation failure, cookie policy rejection, weak password, invalid IDs |
| 401 | Missing/invalid admin or Agent credentials; login failures; 2FA required/invalid |
| 403 | Inactive admin; license gate; Community 3-agent cap; registration IP/identity denial |
| 404 | Missing Agent, rule, VM, notification, GeoIP rule |
| 409 | Hosting Agent restart; Hosting Agent cannot receive rules; security-log identity conflict; hosting profile immutability |
| 413 | License artifact too large (MaxLicenseImportArtifactBytes = 1 MiB) |
| 429 | Login or register rate limiter (middleware; body not a published DTO) |
| 500 | Persistence/token generation failures |
| 503 | Service not initialized (Cloudflare, virtualization, GeoIP lookup, license service, blocking authority) |
SPA / unknown API path
Missing /api/ routes handled by the Manager SPA fallback return:
{"error": "Endpoint not found", "path": "/api/v1/does-not-exist"}That is not a V1ERR envelope.
Rate limiting
POST /api/v1/auth/login—LoginRateLimiter()POST /api/v1/agents/register—RegisterRateLimiter()
Exact 429 JSON is middleware-owned; treat as AUTH_ERR-like or empty body. Do not document bypasses.
Operator troubleshooting
Scroll sideways to see the full table. Use the arrow keys when focused.
| Symptom | Check |
|---|---|
| 400 Secure HTTPS session required | TLS / cookie policy; do not expect a cookie on plain HTTP in production |
| 401 Invalid credentials | Username/password; do not distinguish unknown user vs bad password from the body |
| 403 license object present | Enterprise entitlement, not RBAC |
| 403 COMMUNITY_AGENT_LIMIT_REACHED | Community 3-Agent cap |
| 409 Hosting observation Agents cannot receive… | Hosting profile is observation-only |
Mix of error vs success/data | Parse both envelopes; zwallctl already does |
Related
- Conventions
- Authentication
- License HTTP APIs are Enterprise-only and are provided separately to Enterprise customers. See Enterprise edition.