Administering

Troubleshooting

Symptom, cause, fix. The messages quoted are what a real instance printed when Overpass produced each fault, except where a row says it is unverified. Start with the log, then /api/health.

curl -s http://127.0.0.1:5180/api/health        # {"status":"ok"}; "degraded" means the layout service is down
draughtsman --version                           # which build is this

Where the log is depends on the install: the terminal, docker logs, journalctl -u draughtsman (Linux service), <data>/logs/draughtsman.log (macOS service), or the Windows Application event log. Set logging.file.enabled: true to also write daily files under <data>/logs/ (14 days kept).

It will not start

SymptomCauseFix
Failed to bind to address http://127.0.0.1:5180: address already in use.Another process, often a second copy of Draughtsman, holds the port.Stop it, change server.port, or pass --urls=http://127.0.0.1:5181. lsof -nP -iTCP:5180 -sTCP:LISTEN names the owner. ASPNETCORE_URLS beats server.port.
SQLite Error 14: 'unable to open database file'The account running the server cannot write the data folder.Give the folder to that account, mode 700. In Docker it must belong to uid 10001.
This sqlite database was migrated by a newer version of Draughtsman than this one…, exit code 3You started an older version on a database a newer one upgraded.Start the newer version again, or restore the backup taken before the upgrade. The older one changed nothing. See Backup and upgrading.
Storage migration undone: … was restored from … and is exactly as it was before this start or did not pass its checks: table documents had N rows before the migration…, exit code 4An upgrade's migration failed or lost rows, and the server put the pre-upgrade copy back (the message names it).The data is exactly as it was before that start. Start the previous version again and report the failure with the log. See Upgrading safely.
…was not started: the safety copy it takes first could not be made, exit code 5The disk is full, the data folder is not writable, or data.db already fails SQLite's integrity_check; the upgrade stopped before changing anything.Free space or fix permissions and start again; restore a backup if the file is damaged. To go ahead without a copy, take your own backup and set storage.allowMigrationWithoutBackup: true.
draughtsman config check ends would NOT startA REFUSE line says why: a database a newer version migrated (exit 3), a damaged database, an unreadable draughtsman.yaml, a Postgres database that cannot be reached, or no room for the safety copy.Fix what the line says; the command changed nothing.
draughtsman.yaml: 'server.prot' is not a setting this version reads in the logA mistyped setting, one from a newer version, or one this version removed. It is ignored and the server started.Fix or delete the line; the warning names the nearest real setting.
After an upgrade, Admin > AI or Admin > Email says the stored key or SMTP password "cannot be read"Most often it was written by a build older than this one, which tied it to the folder the program ran from, and the program moved and upgraded in one step. This version no longer ties secrets to a folder, so it can only happen once. Otherwise the key ring's protection (key-encryption key, Keychain item) is not available, or the value is damaged.Name the folder the OLD program ran from in keyRing.legacyInstallPaths (or DRAUGHTSMAN_LEGACY_INSTALL_PATHS) and restart; config check shows Stored secrets. Or restore the key-encryption key, or enter the secret again: nothing else is affected.
Windows: service install refuses, naming a folder under C:\UsersThe service runs as LocalService, which cannot read a user profile; created from there it would fail to start with "Access is denied".Unpack under C:\Program Files\Draughtsman and install from there.
Windows: Expand-Archive fails with a message about a folder that "does not exist"The destination path is about 140 characters or more, past Windows' 260-character limit.Extract into a short path such as C:\Program Files\Draughtsman.
Windows: the first-run page asks for a setup code and Event Viewer shows noneOn a service the code is deliberately not in any log; every local user can read the Application log.From an elevated PowerShell: draughtsman.exe first-run-code --DRAUGHTSMAN_DATA 'C:\ProgramData\Draughtsman'. It refuses once an administrator exists.
Windows: Windows DPAPI cannot be used to protect the key ring and the server stopsThe logon it started from has no DPAPI master key (an SSH public-key session, a scheduled task with no stored password).Choose one of the two safe ways the message names: a key-encryption key, or a deliberate keyRing.protection: none.
Windows: a start-up warning that Users, Everyone or Authenticated Users can read or change the data folderThe folder's inheritance was not cut (a folder made by hand, or an earlier build's install).Run the icacls command the warning prints, or re-run service install. Never add those groups back.
Failure processing application bundle… DOTNET_BUNDLE_EXTRACT_BASE_DIR is not set…The single-file executable unpacks a native library at start and its account has no writable home folder.Set DOTNET_BUNDLE_EXTRACT_BASE_DIR to a writable folder, or give the account a home. service install does this on Linux and macOS.
macOS service exits at once: Draughtsman cannot start: The macOS Keychain cannot be used to protect the key ringA LaunchDaemon has no login keychain. The server will not carry on with an unprotected ring unless you choose that.Give it a key-encryption key (keyRing.protection: key and keyRing.keyFile), or opt out with keyRing.protection: none.
"Cannot be opened because the developer cannot be verified" (macOS) or "Windows protected your PC"The archives are not code-signed or notarised yet.macOS: xattr -dr com.apple.quarantine <folder>. Windows: More info, then Run anyway.
Log: The data folder … is open to other users (mode 755); chmod 700 it unless that is intended.The folder (often a restored one, or an older Docker volume) is readable by others.chmod 700 it. Never chmod 777.
Log: Key ring protection: The key ring is not protected…Linux or Docker with no key-encryption key.Set DRAUGHTSMAN_KEY_ENCRYPTION_KEY or keyRing.keyFile. Harmless if you never store an AI key.
Log: server.knownProxies entry proxy.internal … was ignoredHost names are not understood there.List the proxy's IP address or a CIDR range.

I can reach the server but not use it

SymptomCauseFix
Bad Request - Invalid Hostname (400), but /api/health works on localhostThe Host header is not allowed. A loopback server answers only to localhost; a proxy forwards the public name.Name the host in server.allowedHosts, or list the proxy in server.knownProxies.
GET / answers 401 as plain text and the log says No web build found; serving the API onlyThe web app is not next to the executable (a build tree without the web build).Use a release archive or image.
Sign-in works and you are signed out at onceserver.forceHttps: true while browsing over plain http://, or the proxy loses https.Browse over https://, or turn forceHttps off until TLS works. Check the proxy sends X-Forwarded-Proto and is in knownProxies.
Sign-in answers 429 Too many failed attempts from this account or network address; try again in 15 minutes.Five failures for the account from that address, or twenty from the address, in 15 minutes. Behind an unlisted proxy everyone shares one address.Wait 15 minutes or restart the server. Fix knownProxies.
First-run page: Invalid setup codeWrong code, or the server restarted and issued a new one.Read the newest First-run setup code: in the log.
First run is gone and nobody remembers the administrator's passwordFirst run closes for good once one account exists.If another administrator exists, they use Users, Create reset link. If the only one is locked out: draughtsman reset-admin <email> --generate on the host. See Password recovery and First run.
403 CSRF validation failed - Missing or invalid X-XSRF-TOKEN header.A script using a browser session cookie sent a write without the CSRF header.Use an API token (Authorization: Bearer dst_…), which needs no header.
401 with a token that workedIt expired, was revoked, its owner's password was reset, or the account was deactivated.Make a new token. The 401 never says which.
403 Read-only tokenThe token is read-only and the request writes.Make a full-access token.
413 from a proxy when saving or uploadingThe proxy's body limit (nginx: 1 MB) is below the server's (10 MiB).client_max_body_size 12m;
504 or a dropped connection generating a diagram from textThe proxy gave up waiting for the model.Raise the proxy's timeout to at least 330 seconds.
429 with Retry-After on PDF, layout, import, AI, MCP or thumbnail callsA limits rate or concurrency cap.Slow the caller, or raise limits.*.
Everyone shows the same IP in the security logThe proxy is not in knownProxies, or does not send X-Forwarded-For.See Deployment.
412 Document has changed or 428 Base version required through the APIA save must say which version it was made from (If-Match); another writer saved in between.Read it again, take its ETag, redo the change. In the editor, a clash on something you both changed raises the "Out of date" banner: Reload theirs, Keep mine, or Save mine as a new document.
A deleted diagram is missingDeleting moves it to the bin.Bin on the home page, then Restore. It stays 30 days.
A colleague deleted or overwrote my diagramEvery Editor can change any diagram.Restore from the bin or from History.
Uploading a logo says The SVG could not be parsed: For security reasons DTD is prohibited…The SVG begins with a <!DOCTYPE …> (common from design tools).Delete the XML declaration and DOCTYPE lines and upload again.

Something is degraded

An administrator's first stop is Status (Admin, Status), a read-only list of the parts whose failure the product otherwise survives quietly: the layout service, PDF export, the AI provider, storage, the data folder and the version. It gives the reason, not just a colour.

The System status page listing the layout service, PDF export, AI provider, storage, data folder and version, each with OK or Off and a sentence of detail.
The Status page.
SymptomCauseFix
/api/health says degraded; Status shows "Layout service: Not running"; layout answers 503 The layout engine is not available.The Node sidecar did not start. The log says why.An archive and the image carry Node: do not set sidecar.nodePath unless you mean to. Editing and saving still work; layout, Tidy, SQL import, AI generation and exported connector routes do not. The server restarts the sidecar with back-off.
501 PDF export is not available from GET …/pdf or the render_document tool (the editor's File, Export PDF… still works: it prints from the browser)Server-side PDF needs a headless Chromium or Chrome, which is not bundled, and is off by default. export.pdfProblem says disabled, driver or browser. An administrator sees a note about it on the Status page.browser: set export.chromium.path to a Chrome, or install the pinned Chromium the message names. driver: unpack the archive again over the install, keeping .playwright/ whole; installing a browser does not help. See Install. If you only need a PDF by hand, use File, Export PDF… and choose Save as PDF.
504 from PDF export, or health says PDF export did not finish within 60 seconds, so the browser it was using was stoppedThe browser started but never printed (seen with Microsoft Edge under a Windows service). The server stopped it and its driver by process id and nothing else.Use Playwright's Chromium instead of Edge, or raise export.chromium.timeoutSeconds for a very large diagram. See Install, PDF on Windows.
Status says PDF export is Not installed although export.chromium.enabled: trueStatus shows the same launch check /api/health uses; the text says whether the browser or the driver is missing (earlier builds said OK with no browser installed).Follow the reason. browser: set export.chromium.path or install the pinned Chromium it names. driver: unpack the archive again, keeping .playwright/ whole; installing a browser will not help.
File, Export PDF… opens a print window that is blank, or nothing happensThe browser blocked the print window. The editor falls back to printing from a hidden frame in the same page; some browsers still need the print dialog to be allowed for this site.Allow pop-ups for this address, then try again. The page options (size, orientation, margin) are in the dialog; choose the same paper size in the browser's print dialog.
The browser's PDF has its own header and footer (the page address, a date)The file is made by your browser's print dialog, which can add them.Switch off Headers and footers in the print dialog. The page's own margin is zero, so Draughtsman leaves no margin area for them.
Exported SVG, PNG or PDF has a line of small text under the diagram: Evaluation copy of Draughtsman: licence required for production use.This copy has no verified licence file (unlicensed, or the file did not verify), so rendered exports carry the evaluation notice. Data exports (DSL, JSON, backups) never do.Put a valid licence file in place; the next export is unmarked with no restart. See Import and export and Licensing. To change the contact the line ends with, set about.supportContact.
A document card on the Documents page shows a symbol, or a plain grey picture, instead of the diagramThe thumbnail request failed or was over a limit (the symbol, and the next visit tries again); or the diagram is too large to draw (over 400 nodes and edges it is plain boxes, over 6,000 a grey placeholder); or the layout engine is not running.Reload; check Status for the layout service. Use the List view if you prefer. See The Documents page.
403 reading a theme from a web address; the page says reading a page by its address is switched off on this serverthemes.fetchFromUrl.enabled is false (the default).Paste the page's CSS instead, or have the operator turn the setting on. See From a website. A fetch can also fail as invalid address, scheme refused (https only), blocked address (loopback, private or metadata addresses are refused unless the host is listed in themes.fetchFromUrl.allowedHosts), redirect refused, too large, not CSS, unreachable or timed out.
AI is off after an upgrade, and the AI page says openai may only use api.openai.com. To use another host, an operator lists it under ai.allowedEndpointHosts…The endpoint in draughtsman.yaml, or saved on the page earlier, is a host the new endpoint policy refuses.List the host under ai.allowedEndpointHosts in draughtsman.yaml and restart; the admin page cannot add to it. Then enter the API key again if the host changed. See Where the AI endpoint may point.
Saving an AI endpoint says The endpoint is a link-local or cloud-metadata address, which is never allowed, or An API key is never sent over plain http except to this machineThose rules apply even to a listed host: metadata addresses are never allowed, and a key never travels over plain http except to loopback.Use an https endpoint. For a proxied Ollama that sends a token, use https too. A gateway that redirects must be addressed at its final URL (redirects are not followed).
draughtsman diff or check exits 2A file could not be read or parsed; the message names the file, line and column. (Exit 1 from diff means the diagram changed, and from check that it has an error finding: not faults.)Fix the path or the syntax. In a CI job, make sure the history is fetched (fetch-depth: 0) so the merge base exists. See Diagrams in git.
Import draw.io or Import Visio says the source could not be importedA refused file: a DOCTYPE in a draw.io file; a .vsdx that is not a Visio drawing, an old binary .vsd, a password-protected file, or one over the size limits (3,000,000 bytes for Visio).The message names the reason and what to do: save an old .vsd as .vsdx in Visio, remove any password, or split a very large file. See Moving from draw.io, Visio and Lucidchart.
No AI panel in the editorNo provider is configured: the panel is hidden, not broken.Admin, AI.
AI Test connection: Could not reach 127.0.0.1:1. Check the endpoint, and that the server is running and reachable from this machine.Wrong endpoint, model server down, a firewall; in Docker, localhost is the container.Use http://host.docker.internal:11434 for a host Ollama.
AI Test connection: No API key is set. Paste one here, or set the environment variable DRAUGHTSMAN_AI_KEY.A keyed provider with no key.Paste one, or set the variable.
After a restore, the AI page says the stored key must be entered againThe key ring is not in a backup unless you ask.Enter the key again. It works.
Licence says Invalid: The file is not a complete Draughtsman licence. It may have been cut short or edited.The file is damaged, or this build has no production verification key yet.Re-download the file untouched. Nothing is blocked either way. See Licensing.
Disk space under ~/.net/draughtsman/ growsThe single-file executable unpacks a small library per distinct build and never cleans up.Stop the server and delete that folder, or set DOTNET_BUNDLE_EXTRACT_BASE_DIR.
Logs are hugeFramework logging at Information.logging.frameworkLevel: Warning, the default.

Forgotten passwords and email

SymptomCauseFix
The sign-in page has no Forgot password?, only "Ask your administrator for a reset link"Emailed links are not on: email.provider is not set (or is broken), server.publicUrl is not set, or auth.passwordReset.selfService is false.Open Admin, Email: it says what is missing. Meanwhile an administrator can use Users, Create reset link.
Forgot password? says a link was sent but nothing arrivesThe answer is the same for every address on purpose. The address may have no active account; the mail server may have refused it; at most three emails go to one address in 15 minutes.In Security, look for Password reset requested, then Reset email sent (handed to the mail server) or could not be sent (with the reason). Check spam.
Test email: Could not connect to host:587Wrong host or port, or a firewall.Check the mail server and port on the Email page; test from the server with nc -vz host 587.
The secure connection (STARTTLS) … failed: The remote certificate is invalidThe mail server's certificate is not trusted by this host (self-signed, unknown issuer, or a name that does not match).Use the name on the certificate as the host, or install the issuing certificate on this machine. There is no setting to skip the check.
did not accept the user name or passwordWrong credentials, or the provider needs an app password, SMTP AUTH switched on, or credentials made in its own console.Check the user name and where the password comes from (the page says). See the provider notes under Start from.
The Email page refuses port 465, or email.smtp.tls is "none" but a user name is setImplicit TLS on 465 is not supported, and Draughtsman will not send a password to another machine unencrypted.Use your provider's port 587 with STARTTLS, or drop the user name for a relay that needs none.
A field on the Email page is read-only with "Set in draughtsman.yaml"A value in the file (or the password from the environment) wins and locks it.Edit the file and restart, or remove the key to edit it on the page.
A link says This reset link is not valid. It may have expired or already been used.Used, expired (60 minutes emailed, 24 hours from an administrator), replaced by a newer one, the password was changed another way, the account was deactivated, or a mail client wrapped the line and broke it.Ask for a new one. The Security log's Reset link refused row gives the class of reason.
A link opens a page saying "This page opens from a reset link"The #token=… part did not arrive, or the page was reloaded after it read the link (it removes the secret from the address bar on purpose).Open the link again from the message.
Too many attempts on the reset page or when asking for a linkMore than ten requests from one network address in 15 minutes (three for one email), or twenty failed uses. Counters are in memory.Wait 15 minutes, use another network, or restart the server. Nothing was locked on any account.

Details: Password recovery and email.

An AI agent cannot connect (MCP)

ConfigurationSymptom and causeFix
HTTP with no Authorization headerDynamic Client Registration rejected (HTTP 401). Every route needs a token, and Claude Code prefixes the server's hint with its own OAuth wording.claude mcp add --transport http draughtsman https://host/mcp --header "Authorization: Bearer dst_…"
HTTP, token given, 401 laterThe token expired, was revoked, or its owner's password was reset.A new token.
HTTP, read-only tokenReads work; create_document and patch_document refuse.A full-access token.
HTTP, hangs after 30 or 60 secondsA proxy timeout or response buffering.Raise the timeout and turn buffering off for /mcp.
HTTP, /mcp is 404mcp.enabled: false in draughtsman.yaml.Set it to true and restart.
stdio via plain dotnet runJSON Parse error: Unrecognized token 'U': dotnet run prints Using launch settings from… on standard output.Use dotnet run --no-launch-profile …, or better the packaged draughtsman mcp --stdio.
stdio, starts but sees no diagramsA different data folder from the web server's.Pass the same DRAUGHTSMAN_DATA.

Still stuck

Collect the output of draughtsman --version, GET /api/health as an administrator (for the detail), the last 100 log lines (the log never contains passwords, tokens or API keys), and your draughtsman.yaml with any connection string and secrets removed. Send them to the support address on the application's About page. The full table of causes, with more rows, is the troubleshooting guide in the docs folder of the archive.

The About page: the Overpass logo, version 0.1.0, build date 1 October 2026, licence state Unlicensed evaluation, the support address, a link to the guides on this server and a link to the third-party licence notices.
The About page, available to everyone who is signed in. The support address is set with about.supportContact.