Error codes
Every stable MRD error code the engine reports, with its cause and its fix.
Every operator-facing error the engine reports carries a stable MRD-nnnn code. A code is never renumbered or reused. It appears on the terminal (engine-dmo check, a refused boot), in the log line’s error_code attribute, in engine-dmo doctor --include-logs, on the diagnostics screen, in an error report’s error_code tag, and in the catalogue below with its cause and its fix. Search this handbook for a code to find it.
Configuration
Codes MRD-1nnn.
MRD-1001 A configuration file cannot be read
Cause. The file named in the message is missing or the engine’s user cannot read it. Every project has config/engine.yaml.
Fix. Check the path given to --project, the file’s permissions, and that the container mounts the project’s config/ directory.
MRD-1002 A configuration file is not valid YAML
Cause. A tab used for indentation, an unclosed quote or bracket, or a value that starts with a character YAML reserves (@, a backtick, %).
Fix. Fix the line the caret points at. Quote a value that starts with a reserved character.
MRD-1003 A configuration key is not one the engine knows
Cause. A typo, or a key from a newer release. Unknown keys are refused rather than ignored, so a misspelt setting cannot silently do nothing.
Fix. Use the key the hint suggests, or remove it. engine-dmo config schema prints every key the binary knows.
MRD-1004 A secret is written into the configuration as a literal
Cause. Configuration is committed to version control and must never hold a secret. Every secret path (config.SecretPaths) and every telemetry.otlp.headers value must be a bare ${VAR} interpolation.
Fix. Write the value as ${VAR}, set the variable in the environment, and rotate the secret that was written down.
MRD-1005 An environment variable the configuration names is not set
Cause. The configuration interpolates ${VAR} and the process environment has no such variable.
Fix. Set the variable, or for a value that is not a secret give it a default with ${VAR:-default}.
MRD-1006 A project file breaks a rule
Cause. A value in engine.yaml, a schema type, a route, a template or another project file breaks the rule the message states: a duration, size or schedule that cannot be read, a value outside its set, a name that does not resolve, or two settings that contradict each other. It is the code of every project diagnostic without a more specific one.
Fix. Change the value at the line and column given. engine-dmo check reports every problem in one run.
MRD-1007 A key has moved out of engine.yaml
Cause. The setting now lives in a file of its own.
Fix. Move the value to the file the message names.
MRD-1008 The project configuration is not valid
Cause. A site, route, schema type, role or template setting under config/ breaks a rule; the diagnostics above this line name each one.
Fix. Run engine-dmo check and fix every error it lists.
Migrations and schema
Codes MRD-2nnn.
MRD-2001 The database has migrations the binary has not applied
Cause. A new release added migrations and migrate.on_boot is refuse, the production default, so the engine will not serve until they are applied.
Fix. Back up, then run engine-dmo migrate up (or set migrate.on_boot: apply outside production).
MRD-2002 A migration failed to apply
Cause. A statement in the migration failed, usually against data the migration did not expect or a lock it could not take. Migrations run in a transaction, so nothing was half applied.
Fix. Read the statement and error in the message, fix the data or wait for the lock, and run engine-dmo migrate up again. Send the doctor bundle if the cause is not clear.
MRD-2003 The database is newer than this binary
Cause. The database has migrations this binary does not know: a newer release ran against it, or a rollback went to an older binary.
Fix. Run the release that migrated the database. Migrations are forward only; restoring the backup taken before the upgrade is the only way back.
MRD-2004 The schema in the database differs from the configuration
Cause. The content types in config/schema/ changed and schema.on_drift is refuse, so the engine will not serve a model the database was not reconciled to.
Fix. Run engine-dmo schema plan, review it, then engine-dmo schema apply.
MRD-2005 Applying the schema plan failed
Cause. A step of the reconciliation plan was refused, typically a destructive change without its confirmation or data that breaks a new constraint.
Fix. Run engine-dmo schema plan to see the step and its reason, and follow the hint it prints.
Boot and runtime
Codes MRD-3nnn.
MRD-3001 The engine cannot reach the database
Cause. The database is down, the URL is wrong, a firewall drops the connection, or the credentials are refused.
Fix. Check database.url and that PostgreSQL is answering. engine-dmo doctor prints the host, the database and the error.
MRD-3002 The database server is older than the engine supports
Cause. The PostgreSQL server is older than 14, the oldest the engine supports.
Fix. Upgrade PostgreSQL to 14 or later.
MRD-3003 The engine cannot listen on its address
Cause. Another process holds the port, or the engine’s user may not bind a port below 1024.
Fix. Change server.listen or stop the other process. telemetry.metrics.bind must be a different address.
MRD-3004 The templates failed the linter at boot
Cause. A template has a security finding, which refuses a production boot whatever template.strict says, or an unknown variable under template.strict: true.
Fix. Run engine-dmo check for the findings with their lines, and fix each one.
MRD-3005 A request panicked
Cause. A bug: a handler reached a state it did not expect. The visitor got a 500, the stack was logged and reported, and the engine kept serving.
Fix. Send the doctor bundle with --include-logs 20 and the request id from the error. If an error reporter is configured, the report holds the stack.
MRD-3006 A job used its last attempt
Cause. The job’s handler failed on every attempt, or no handler is registered for its kind. The job is kept as dead with its last error.
Fix. engine-dmo jobs list --failed shows the error and the request that queued it. Fix the cause, then engine-dmo jobs retry <id>.
MRD-3007 A job panicked
Cause. A bug in the job’s handler. The attempt counts as failed and the job is retried with back-off.
Fix. Send the doctor bundle with --include-logs 20; the report holds the stack.
MRD-3008 A scheduled task failed
Cause. A task on the scheduler’s leader returned an error; it runs again at its next time.
Fix. The message names the task and the error. engine-dmo schedule run <task> runs it again once the cause is fixed.
MRD-3009 A scheduled task panicked
Cause. A bug in the task. The run counts as a failure and the scheduler carries on.
Fix. Send the doctor bundle with --include-logs 20; the report holds the stack.
Storage
Codes MRD-4nnn.
MRD-4001 The object storage bucket failed the boot probe
Cause. At boot the engine writes, reads back and deletes a small object. A wrong key, a policy that denies one of the three verbs, a missing bucket or an unreachable endpoint fails it.
Fix. Check storage.s3 and the bucket policy: the engine needs put, get, head, delete and list.
MRD-4002 The local storage directory cannot be written
Cause. storage.filesystem.root cannot be created or written: it belongs to another user, or its volume is full or read only.
Fix. Create the directory, give the engine’s user write access, and check free space.
MRD-4003 The object store refused a request
Cause. S3 answered with a refusal such as AccessDenied or NoSuchBucket; refusals are not retried.
Fix. The message carries S3’s own error code. Fix the credentials or the policy.
MRD-4004 An upload was refused because its metadata could not be removed
Cause. The media pipeline strips location and camera metadata, and a file whose metadata it cannot strip is refused rather than stored.
Fix. Re-export the file without metadata and upload it again.
Search
Codes MRD-5nnn.
MRD-5001 The search backend did not answer
Cause. The backend is down, the URL is wrong, or the credentials are refused. Public search falls back to browse mode.
Fix. Check the backend’s health and search.* in engine.yaml.
MRD-5002 The search circuit breaker is open
Cause. Enough recent queries failed that the engine stopped asking the backend for a while.
Fix. Fix the backend; the breaker closes on its own once a probe succeeds.
MRD-5003 Indexing a document failed
Cause. The backend refused a document, typically a mapping conflict after a schema change.
Fix. Run engine-dmo search verify, then engine-dmo search rebuild for the site.
Codes MRD-6nnn.
MRD-6001 The mail provider failed
Cause. A transport failure, a 5xx or a 429 from the provider. The delivery is retried.
Fix. Check the provider’s status page. Retries continue on their own.
MRD-6002 The mail provider rejected a message
Cause. A 4xx such as an unverified sender, an invalid recipient or refused credentials. Not retried.
Fix. Read the provider’s message in the delivery record; a 401 is the credential.
Telemetry and error reporting
Codes MRD-7nnn.
MRD-7001 Exporting traces or metrics failed
Cause. The OTLP endpoint did not answer, refused the headers, or rejected the payload. Telemetry is dropped, never queued without bound, and serving is not affected.
Fix. Check telemetry.otlp.endpoint and its headers. The diagnostics screen and engine-dmo doctor show the last error.
MRD-7002 Sending an error report failed
Cause. The error reporter’s endpoint did not answer or refused the report. Reports are dropped, never queued without bound.
Fix. Check telemetry.errors.dsn, then run engine-dmo telemetry test.
Content API problem types
Codes MRD-8nnn.
MRD-8001 Content API: no such site
Cause. The request names a site the install does not have, or one that is not headless.
Fix. Use a site key from engine-dmo describe project.
MRD-8002 Content API: not found, or not visible
Cause. No published document matches, or the key may not read it.
Fix. Check the id or path, and that the document is published on the site.
MRD-8003 Content API: the field is not indexed
Cause. A filter or sort names a field that is not declared queryable.
Fix. Declare the field queryable in the schema, or filter on another field.
MRD-8004 Content API: a parameter is not valid
Cause. A parameter could not be read; the parameter member names it.
Fix. Fix the parameter as the detail says.
MRD-8005 Content API: a limit was exceeded
Cause. A page size, expansion depth or filter count is above its limit.
Fix. Ask for less, or page through the result.
MRD-8006 Content API: the engine could not answer
Cause. An error inside the engine; it is logged with the request id.
Fix. Retry. If it persists, send the doctor bundle with the request id.
MRD-8007 Content API: the key is missing, unknown, expired or revoked
Cause. The Authorization header holds no key the install knows, or one past its expiry or revoked.
Fix. Issue a key under Settings, API keys, and send it as a bearer token.
MRD-8008 Content API: a secret key was sent from a browser
Cause. A secret key arrived with an Origin header, so it is in front-end code. It is marked exposed and administrators are told.
Fix. Rotate the key, and use a publishable key in the browser.
MRD-8009 Content API: the key does not read this site
Cause. The key’s sites do not include the one requested.
Fix. Add the site to the key, or use the site’s own key.
MRD-8010 Content API: the origin is not allowed for this key
Cause. A publishable key was used from an origin it does not list.
Fix. Add the origin to the key.
MRD-8011 Content API: the key does not hold the capability
Cause. The operation needs a capability, such as preview, that the key was not given.
Fix. Issue a key with the capability.
MRD-8012 Content API: the preview has expired
Cause. Preview tokens end with the staff session that issued them.
Fix. Open the preview again from the editor.
MRD-8013 Content API: the preview token is not valid
Cause. The token was altered, or signed under a key the install no longer holds.
Fix. Open the preview again from the editor.
MRD-8014 Content API: too many requests
Cause. The key or address used its quota; Retry-After says when to try again.
Fix. Back off as Retry-After says, or cache responses on the frontend.
MRD-8015 Content API: a form submission was not valid
Cause. A post to a form through the content API failed the form’s own validation; field_errors names each field and why.
Fix. Show the field errors to the visitor and let them correct the form.
Exit codes
The five exit codes every engine-dmo and engine-cms command uses (0 success, 1 error, 2 pending or unconfirmed, 3 invalid configuration, 4 degraded), and which commands return 2 and 4 and why.
For agents
Start here if you are a coding agent building or changing a Meridian website. What Meridian is, the golden rules, how to read the rest of the handbook from the binary, and the change, check, render loop.