ODBC Adapter Setup Guide
The ODBC connector talks to your database through an adapter, not directly. MaestroHub is a pure-Go product with no native database drivers of its own; the MaestroHub ODBC Adapter is a small standalone service that owns the ODBC stack. You run it on a host that has the platform's ODBC driver manager and your database's ODBC driver installed, and MaestroHub connects to it over a secure WebSocket.
This guide covers section 1 of 2: getting the adapter downloaded, configured, and running. Once it is up, continue to the ODBC Connector Guide to create the connection inside MaestroHub.
┌─────────────┐ wss:// (TLS) ┌──────────────────────┐ ODBC
│ MaestroHub │ ───────────────────► │ MaestroHub ODBC │ ─────────► Your Database
│ (Go) │ JSON over 1 socket │ Adapter (this guide) │ driver (DB2, Sybase,
│ │ = 1 session = 1 conn │ │ manager Informix, …)
└─────────────┘ └──────────────────────┘
- Hop 1 — MaestroHub → Adapter: a secure WebSocket (
wss://) authenticated with a bearer token. - Hop 2 — Adapter → Database: a normal ODBC connection opened by the adapter using your database credentials.
The adapter is a network gateway, not an on-box agent — it only needs to run somewhere that can reach the database. It never stores your database credentials: those arrive per-connection from MaestroHub, live in memory only for the life of the socket, and are never written to logs.
When you need the adapter
Use the ODBC connector (and therefore this adapter) for the long tail of databases that have no native MaestroHub connector — IBM Db2, Sybase / SAP ASE, Teradata, Informix, Progress OpenEdge, Vertica, Firebird, Excel/Access, and other proprietary or legacy engines.
If MaestroHub already ships a native connector for your database — PostgreSQL, MySQL, SQL Server, Oracle, ClickHouse, Snowflake, and others — use that instead. It needs no adapter and no driver installation. The ODBC connector is the universal fallback, not the first choice.
System requirements
| Requirement | Detail |
|---|---|
| OS | Linux (x64 / arm64), Windows 10 / Server 2016+ (x64 / arm64), or macOS (x64 / arm64) |
| Runtime | None — published builds are self-contained (.NET 8 is bundled, no separate install) |
| ODBC driver manager | Windows: built in. Linux/macOS: install unixODBC. (The Docker image already includes it.) |
| Database ODBC driver | The specific ODBC driver for your target database, installed and registered on the adapter host |
| Network | The adapter host must be able to reach the database; MaestroHub must be able to reach the adapter on its listen port (default 45283) |
The named ODBC driver (e.g. IBM DB2 ODBC DRIVER) must be installed on the machine running the adapter. MaestroHub never loads it. Verify what is installed with --print-drivers (below) before configuring the connection.
1. Download the adapter
Download the build for your OS and CPU architecture from the MaestroHub downloads portal:
https://portal.maestrohub.com/downloads/plugins
Pick the archive matching your host:
| Platform | Archive |
|---|---|
linux-x64 | maestrohub-odbc-adapter-<version>-linux-x64.tar.gz |
linux-arm64 | maestrohub-odbc-adapter-<version>-linux-arm64.tar.gz |
win-x64 | maestrohub-odbc-adapter-<version>-win-x64.zip |
win-arm64 | maestrohub-odbc-adapter-<version>-win-arm64.zip |
osx-x64 / osx-arm64 | …-osx-*.tar.gz |
Extract the archive. Inside you will find the executable (maestrohub-odbc-adapter / maestrohub-odbc-adapter.exe), a sample appsettings.json, the operator README.md, LICENSE, and ThirdPartyNotices.txt.
2. Verify the host
Before running the service, sanity-check the host with the two diagnostic verbs. These exit immediately and never start the server.
List the ODBC drivers and DSNs the host exposes:
# Linux / macOS
./maestrohub-odbc-adapter --print-drivers
# Windows
maestrohub-odbc-adapter.exe --print-drivers
The driver name you later enter in MaestroHub must match one of the driver strings printed here exactly — it is the driver manager's registered name, not the product name.
Validate config, TLS certificate, and driver manager in one shot:
./maestrohub-odbc-adapter --check
--check exits non-zero if anything is wrong, so it is the fastest way to catch a missing driver manager or a broken certificate before going live.
3. First run — generate the token and certificate
Run the adapter once interactively before installing it as a service. On first run it bootstraps everything it needs:
# Linux / macOS
./maestrohub-odbc-adapter
# Windows
maestrohub-odbc-adapter.exe
On this first run the adapter:
- writes a starter
appsettings.jsonbeside the binary, - generates a self-signed TLS certificate and prints its SHA-256 fingerprint — pin this in MaestroHub,
- generates an API bearer token and prints it once — store it now; it is not printed again,
- then listens on
https://0.0.0.0:45283and servesGET /health.
The API token is printed once and never again. If you miss it, set a known token explicitly (--token <value>, or auth.token in appsettings.json, or MHODBC_TOKEN) and restart. You will paste this token into the MaestroHub connection's API Token field.
4. Configure the adapter
Configuration is layered — later sources override earlier ones:
built-in defaults → appsettings.json → MHODBC_* env vars → command-line flags
appsettings.json is generated on first run and lives beside the binary (override its path with --config <path>). Keys are camelCase and map 1:1 onto the settings.
Settings reference
| Setting | appsettings.json | Env var | CLI flag | Default | Meaning |
|---|---|---|---|---|---|
| Bind address | listen | MHODBC_LISTEN | --listen | 0.0.0.0 | Interface to bind. Use a reachable interface, not 127.0.0.1, if MaestroHub is on another host. |
| Port | port | MHODBC_PORT | --port | 45283 | Listen port. Allow it through the host firewall. |
| TLS on/off | tls.enabled | MHODBC_TLS_ENABLED | --tls[=…] / --no-tls | true | wss/HTTPS. --no-tls is local testing only. |
| TLS cert | tls.certPath | MHODBC_TLS_CERT | --tls-cert | (generated) | PEM certificate path. |
| TLS key | tls.keyPath | MHODBC_TLS_KEY | --tls-key | (generated) | PEM private-key path. |
| API token | auth.token | MHODBC_TOKEN | --token | (generated) | Bearer token required on the WebSocket upgrade. |
| Max message size | limits.maxMessageBytes | MHODBC_MAX_MSG | --max-msg | 16777216 (16 MiB) | Max inbound message; larger requests fail with MH002. |
| Max rows | limits.maxRows | MHODBC_MAX_ROWS | --max-rows | 1000000 | Hard ceiling on rows per query (safety cap behind each query's own maxRows). |
| Idle timeout | limits.idleTimeoutSeconds | MHODBC_IDLE_TIMEOUT | --idle-timeout | 300 | Reap a silent session after N seconds; 0 disables. A long-running command is never cut off. |
| Log level | logging.level | MHODBC_LOG_LEVEL | --log-level | Information | Trace … Critical. |
| Log file | logging.file | MHODBC_LOG_FILE | --log-file | (console only) | Also write logs to this file. |
Example appsettings.json
{
"listen": "0.0.0.0",
"port": 45283,
"tls": { "enabled": true, "certPath": "adapter.crt", "keyPath": "adapter.key" },
"auth": { "token": "…the token printed on first run…" },
"limits": { "maxMessageBytes": 16777216, "maxRows": 1000000, "idleTimeoutSeconds": 300 },
"logging": { "level": "Information", "file": null }
}
There is no database username or password in adapter config. Those are supplied per-connection by MaestroHub in the connection profile and held in memory only — they are never written to appsettings.json or to logs.
Command-line reference
maestrohub-odbc-adapter [options]
VERBS:
--version Print adapter and protocol version, then exit.
--print-drivers List detected ODBC driver managers, drivers, and DSNs, then exit.
--check Validate config, TLS cert, and driver manager; non-zero exit on problems.
--install-service Install as a Windows Service / systemd unit (run elevated).
--uninstall-service Remove the installed service.
--help, -h Show help.
CONFIG OVERRIDES (also via appsettings.json and MHODBC_* env vars):
--config <path> Path to appsettings.json (default: beside the binary).
--listen <addr> Bind address (default 0.0.0.0).
--port <n> Listen port (default 45283).
--tls[=true|false] Enable TLS / wss (default true). --no-tls disables it (local testing only).
--tls-cert <path> PEM certificate path.
--tls-key <path> PEM private-key path.
--token <value> API bearer token (generated on first run if unset).
--max-msg <bytes> Max inbound WebSocket message size.
--max-rows <n> Hard cap on rows returned per query.
--idle-timeout <s> Idle session timeout in seconds.
--log-level <level> Trace|Debug|Information|Warning|Error|Critical.
--log-file <path> Also write logs to this file.
Flags accept both --key value and --key=value forms.
5. Install the database ODBC driver
The adapter always needs an ODBC driver for the target database present on the host — the driver manager plus the specific driver.
- Windows — the driver manager is built in. Install the vendor's ODBC driver (e.g. IBM Data Server Driver for ODBC, Progress OpenEdge ODBC) and confirm it appears under ODBC Data Sources (64-bit) or via
--print-drivers. - Linux / macOS — install unixODBC first, then the vendor driver, and register it in
odbcinst.ini. Confirm with--print-drivers.
After installing a driver, re-run --print-drivers and note the exact driver string — you will type it into the connection's ODBC Driver field.
The adapter supports both styles, and so does the connector:
- DSN-less (driver mode): you give the driver name plus server/port/database directly. No DSN registration needed.
- DSN mode: you pre-register a DSN on the adapter host (Windows ODBC Administrator, or
odbc.inion unixODBC) and reference it by name. Use this when your DBA already manages DSNs centrally.
6. Run the adapter
Interactively (foreground)
# Linux / macOS
./maestrohub-odbc-adapter --check # verify the host first
./maestrohub-odbc-adapter --listen 0.0.0.0 --port 45283
# Windows
maestrohub-odbc-adapter.exe --check
maestrohub-odbc-adapter.exe
The adapter logs its bind address on startup — confirm it matches the host/port you will dial from MaestroHub.
Health endpoints (served whether or not a client is connected):
| Endpoint | Meaning |
|---|---|
GET /health | Process is up (liveness). |
GET /health/ready | ready normally; stopping + 503 while draining on shutdown. |
As a service (production)
From an elevated shell (Administrator on Windows, sudo on Linux):
maestrohub-odbc-adapter --install-service # Windows Service / systemd unit
maestrohub-odbc-adapter --install-service --service-name my-adapter # custom name
maestrohub-odbc-adapter --uninstall-service
The installed service reads its configuration from appsettings.json (beside the binary) and MHODBC_* env vars — not from install-time flags. Run the adapter once interactively first (step 3) so it generates and prints the API token and TLS fingerprint before the non-interactive service starts. On macOS, --install-service prints a ready-to-use launchd recipe instead of installing automatically.
With Docker
docker run -d -p 45283:45283 -v mh-odbc-data:/data maestrohub-odbc-adapter:latest
The image is non-root, exposes port 45283, and stores its generated appsettings.json + TLS cert in the /data volume — mount a volume there to persist the API token and certificate across container recreation.
The image bundles only license-safe drivers: unixODBC, PostgreSQL psqlODBC, and MariaDB Connector/ODBC (which also speaks to MySQL servers). To use a driver that cannot be redistributed (e.g. Microsoft's SQL Server driver), layer it into a child image:
FROM maestrohub-odbc-adapter:latest
USER root
# Example: Microsoft ODBC Driver for SQL Server (proprietary EULA — you accept it here)
RUN apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql18 && rm -rf /var/lib/apt/lists/*
USER appuser
The adapter bundles only license-safe components (unixODBC, psqlODBC, MariaDB Connector/ODBC, IBM Db2 clidriver). The Microsoft SQL Server driver (msodbcsql18) and Oracle's MySQL Connector/ODBC are never bundled — install those on the host yourself. See ThirdPartyNotices.txt in the download for the full component list.
7. Lifecycle behaviors worth knowing
- Idle reaping — a connection that authenticates then goes silent past
idleTimeoutSeconds(default 300s) is closed cleanly (not reported as an error). Raise--idle-timeout, set0to disable, or let MaestroHub's keep-alive pings hold the session open. - Graceful shutdown / drain — on
SIGTERM/ Ctrl-C the adapter stops accepting new sockets (503on upgrade,/health/ready→stopping) and new commands, but lets the in-flight command finish before closing. The drain backstop is 30 seconds.
Troubleshooting the adapter
Start with --check and --print-drivers — most issues below are diagnosable from those two verbs.
Startup & connection
| Symptom | Likely cause | Fix |
|---|---|---|
Address already in use on startup | another process holds the port | change --port, or free the port; confirm --listen is an interface that exists |
| MaestroHub can't reach the adapter | bound to 127.0.0.1, or a firewall blocks the port | bind a reachable interface (--listen 0.0.0.0) and allow the port through the firewall; the adapter logs its bind address on startup |
401 Unauthorized on connect | wrong/missing bearer token | the token in the connection's API Token field must match the adapter's token (printed once on first run / auth.token). If lost, set a new one and restart |
| MaestroHub rejects the TLS certificate | the first-run cert is self-signed | pin its SHA-256 fingerprint by pasting the adapter's certificate into the connection's Adapter CA / Certificate field, or supply a CA-signed cert via --tls-cert/--tls-key. (Skip-verify exists for local testing only.) |
CONNECT / drivers
| Symptom | Likely cause | Fix |
|---|---|---|
Driver / DSN not found (IM* SQLSTATE) | the named driver or DSN isn't installed on the adapter host | run --print-drivers; the ODBC Driver value must match an installed driver string exactly |
Bad credentials (28000) | wrong DB user/password | these come from the connection profile in MaestroHub, not adapter config — fix them there |
CONNECT times out / unreachable (08* or HYT0x) | DB host/port unreachable from the adapter host | verify network reachability from the adapter machine; raise the connection's Connect Timeout |
CONNECT_RESULT shows "dialect": "unknown" | the engine isn't a recognized dialect | expected — query/execute/browse/writes to existing tables still work; only auto-create is gated |
Commands & data
| Symptom | Likely cause | Fix |
|---|---|---|
WRITE with auto-create fails with permanent HYC00 | auto-create needs a recognized dialect; this engine resolved to unknown | pre-create the table, then write without auto-create (auto-create refuses rather than guess a wrong schema) |
Query result short and truncated: true | hit the per-query row limit or the adapter's maxRows cap | raise the limit, or the adapter's --max-rows (it is a safety ceiling) |
MH002 (message too large) | request exceeds limits.maxMessageBytes (16 MiB default) | raise --max-msg, or split the write into smaller batches |
MH001 on connect | client/adapter protocol versions don't overlap | upgrade the adapter so it serves the protocol version MaestroHub requests (currently 1) |
| Session drops after ~5 min idle | idle-timeout reaping (default 300s) | expected; raise --idle-timeout, set 0, or rely on MaestroHub's keep-alive pings |
What you will never see in logs
Database passwords, connection strings, extra connection params, and row values are redacted by design. Errors are classified by SQLSTATE only, never by parsing driver message text — so the sqlState + outcome fields are the authoritative signal, not the human message.
Next step
With the adapter running and a driver installed, continue to the ODBC Connector Guide to create the connection in MaestroHub, point it at this adapter, and build Query / Execute / Write functions.