Skip to content

Platform

Error codes

The unified JSON error format of the gate and DocBuilder, the full error code table with remedies, and when to retry.

On this page

Unified error format#

Every error from the gate (/o3o/*) and DocBuilder (/v1/*) has the same JSON body. Every response carries an X-O3O-Request-Id header equal to request_id.

415Example: unsupported format pair.
{
  "error": {
    "code": "unsupported_format",
    "message": "Không chuyển được từ docx sang xlsx.",
    "detail": {
      "from": "docx",
      "to": "xlsx"
    },
    "request_id": "req_0123456789abcdef"
  }
}

Fields of the <code>error</code> object

  • codestringrequired
    Stable machine-readable string. Branch on this field.
  • messagestringrequired
    Vietnamese sentence for people; wording may change between versions, do not parse it.
  • detailobjectrequiredDefault: {}
    Machine-readable details, possibly empty; never contains document content.
  • request_idstringrequired
    req_ + 16 hex characters; include it when reporting a problem.
  • Branch on code, not on message.
  • For an unknown code (later versions may add codes): fall back to the HTTP status class.
  • Log request_id so it can be matched against the O3O server logs.
  • Two exceptions do not use this JSON shape: the connection-limit HTML page (HTTP 429) shown to users, and /o3o/auth, which only the internal proxy calls.

DocBuilder error codes#

HTTPcodeWhenWhat to do
400bad_requestMissing parameter, broken JSON, wrong options type, neither file nor url.Fix the request using detail.errors (path, message). Do not resend it unchanged.
401unauthorizedMissing or wrong key. detail.reason: missing, invalid, no_keys_configured.Check the Authorization header and the key list. no_keys_configured: no key has been configured yet.
401token_expiredThe JWT has expired.Sign a new JWT and resend.
403forbidden_featureEndpoint or option not included in the current edition. detail.feature, detail.edition.Use another approach available in the edition, or move to the enterprise edition. Do not retry.
404not_foundNo job or file with that id.Check the job_… or file_… id.
410goneThe job or file is past its retention time.Send the original request again; next time download before result_ttl_minutes.
413file_too_largeInput or output file exceeds max_file_mb. detail.limit_mb.Shrink or split the file; see Plan limits.
415unsupported_formatUnknown source format, or an unsupported source–target pair.Check GET /v1/formats; conversion only works within one document family. Pass from when the file name has no extension.
422script_invalidThe script fails JSON Schema validation. detail.errors[].path is a JSON Pointer.Fix the reported locations; validate beforehand with o3oscript-v1.schema.json.
422script_too_largeScript units exceed max_script_units. detail.units, detail.limit.Split the script into several smaller documents.
422script_errorValid script that failed at run time. detail.path points at the offending element.Fix the element at detail.path.
422template_errorUnbalanced loop tags, or missing fields with missing = "error". detail.fields.Balance the {{#…}}/{{/…}} tags within one row; add the data or change options.missing.
422macro_not_allowedThe template sent to POST /v1/template/render contains macros: an OOXML file with a vbaProject.bin part or a macroEnabled content type, or an ODF file with a Basic/ or Scripts/ folder. detail.reason, detail.part; returned immediately even with async = true.Save the template again without macros (for example docm as docx) and resend it. Conversion and extraction still accept files with macros because they load files with macro execution off.
422corrupt_sourceThe source file cannot be opened.Check the file with an office application; do not retry unchanged.
422password_requiredPassword-protected file with a missing or wrong password.Pass options.password (conversion) or password (extraction).
422url_not_allowedThe URL violates the SSRF rules.Use a public http/https URL, or upload the file as multipart. Internal hosts must be added to O3O_FETCH_ALLOW_HOSTS by the administrator.
422download_failedThe source URL could not be fetched (network error, non-200 status, timeout).Check the URL from the O3O server's side; a later retry may succeed.
429rate_limitedRate limit exceeded. detail.window: minute or day.Wait Retry-After seconds, then retry. See Plan limits.
500internalUnexpected error.Retry once; if it repeats, send the request_id to the administrator.
503queue_fullThe queue is full (max_queued_jobs).Wait for Retry-After; send fewer requests in parallel.
503pool_unavailableNo worker process is alive.Retry later; the administrator should check the o3o-docbuilder logs.
504timeoutSynchronous mode exceeded sync_timeout_seconds, or the job exceeded job_timeout_seconds.Heavy file: use async = true. Job timeout: split the work.

Gate and embedding error codes#

The gate shares DocBuilder's three generic codes with the same meaning: not_found (404), bad_request (400, or the original HTTP status such as 405 for a wrong method) and internal (500). The internal WOPI host additionally returns not_implemented (501) for WOPI operations not available in v1. The other codes in the table are specific to the embedding layer.

HTTPcodeWhenWhat to do
400bad_requestShared code, same meaning as in DocBuilder: invalid parameters or body; a method not supported on that path (the HTTP status is kept, for example 405, with detail.method); an empty PutFile body.Fix the request; do not resend it unchanged.
400invalid_configMissing or invalid config field. detail.errors = [{path, message}].Fix the config at each path.
401token_requiredThe server requires a JWT but the config has none.Sign the config on your server, see Authentication.
401invalid_tokenBad signature, not HS256, missing exp, or exp more than 24 hours away.Sign again following the rules.
401token_expiredPast exp.Sign a new token.
401embed_auth_not_configuredThe server has no key and unsigned mode is off.The administrator sets O3O_EMBED_JWT_SECRET.
401invalid_session_tokenAuthorization does not match the session.Use the right session's access_token (api.js does this for you).
403origin_not_allowedOrigin is not listed in O3O_EMBED_ALLOWED_ORIGINS.The administrator adds the page origin to the list.
403invalid_signatureThe download URL signature is wrong.Use the URL exactly as received from the callback or onSaved.
404not_foundShared code, same meaning as in DocBuilder: unknown path, the session or document does not exist, or embedding is disabled.Check the path and the session id; check O3O_EMBED_ENABLED.
410link_expiredThe download URL has expired.Get a fresh URL from GET /o3o/embed/session/{session_id} while the session exists.
410version_goneThe version was cleaned up (the gate keeps the latest 5 plus the original).Download a newer version.
413file_too_largeExceeds O3O_EMBED_MAX_FILE_MB.Reduce the file size or raise the limit on the server.
415unsupported_file_typefileType is not in the accepted list.Use one of: docx, doc, odt, rtf, txt, xlsx, xls, ods, csv, pptx, ppt, odp.
422url_not_alloweddocument.url or callbackUrl violates the SSRF rules.Use a public URL, or have the host added to O3O_FETCH_ALLOW_HOSTS.
422download_faileddocument.url could not be fetched.The URL must answer 200 to the O3O server.
500internalShared code, same meaning as in DocBuilder: an unexpected error inside the gate.Retry once; if it repeats, send the request_id to the administrator.
501not_implementedA WOPI operation not available in v1 (for example X-WOPI-Override values such as PUT_RELATIVE or RENAME_FILE). Only the editing server sees this code, because the proxy does not expose /o3o/wopi/.Nothing to handle on the integration side; the matching feature is coming soon.
503editor_unavailableThe editing server's discovery could not be read.Retry after a few seconds; check upstream.coolwsd in /o3o/status.

The connection_limit_reached code (403) only travels from the gate to the internal proxy. Users never get this JSON: through Nextcloud they see the "connection limit reached" page (HTTP 429), and embedded sessions open read-only with an onLimitReached event. See How connections are counted.

Browser-only codes#

api.js also emits the codes below through the onError event as {code, message, detail}.

codeWhenWhat to do
network_errorThe O3O server cannot be reached.Check the api.js address, CORS and the network; retry.
load_failedThe editor frame reported a load failure, or no document after 120 seconds.Check the source file and O3O_ONLINE_FRAME_ANCESTORS for cross-origin pages.
save_failedThe editing server reported a failed save; detail holds the raw message.Call save() again; the document is still in the session.
save_timeoutsave() took more than 30 seconds.Retry; check the network connection.

When to retry#

GroupCodesAction
Transient429 rate_limited, 503 queue_full, 503 pool_unavailable, 503 editor_unavailable, network_errorRetry after Retry-After (when present) or with growing back-off.
Possibly transient500 internal, 504 timeout, 422 download_failedRetry once; for timeout switch to async = true.
Fix the request400, 413, 415, 422 script_*, 422 template_error, 422 macro_not_allowed, 422 url_not_allowed, 422 password_required, 422 corrupt_sourceNever resend unchanged.
Fix credentials or edition401, 403Fix the key, token, origin or edition.
Nothing to retry404, 410, 501 not_implementedCreate the job again or obtain a new URL; 501 means the feature is not available yet.