UniFi Network¶
UniFi Network is Ubiquiti's network controller. dnsweaver manages DNS policy records on the console via the official UniFi Network Integration API. In the Network app, these appear under Settings → Policy Engine → Policy Table as policies of type DNS.
Requirements¶
- A UniFi OS console (Dream Machine, Cloud Gateway, Cloud Key) or UniFi OS Server (Ubiquiti's self-hosted UniFi OS for Linux)
- UniFi Network 10.6 or later, the oldest release this provider has been verified against. dnsweaver refuses to start against an older or unrecognized version.
- A UniFi gateway (for example a Dream Machine, Cloud Gateway or UniFi Gateway) that serves DNS to your clients
- An Integration API key, created under Settings → Control Plane → Integrations → Create API Key
- Network reachability from dnsweaver to the console's HTTPS port
Records are only answered through a UniFi gateway
The console stores DNS policies whether or not the site has a gateway, and dnsweaver can create, update and delete them either way. Clients only receive answers for these records when they resolve through a UniFi gateway on that site. A UniFi OS Server or Cloud Key without a UniFi gateway accepts the records, but nothing serves them.
Standalone Network Application is not supported
The legacy standalone Network Application (the Linux, Windows, macOS and Docker builds, such as the linuxserver/unifi-network-application image) does not expose the Integration API or API keys, so it has no Integrations page and cannot be used with this provider. Ubiquiti's replacement for it is UniFi OS Server, which does support both.
Official API only
dnsweaver uses the versioned, documented Integration API (/proxy/network/integration/v1), not the undocumented static-dns endpoints older tooling relied on. The legacy endpoints need cookie login and CSRF handling and have no native update; the Integration API needs only an API key.
Configuration¶
environment:
- DNSWEAVER_INSTANCES=unifi
- DNSWEAVER_UNIFI_TYPE=unifi
- DNSWEAVER_UNIFI_URL=https://192.168.1.1
- DNSWEAVER_UNIFI_API_KEY_FILE=/run/secrets/unifi_api_key
- DNSWEAVER_UNIFI_SITE=default
- DNSWEAVER_UNIFI_ZONE=home.example.com
- DNSWEAVER_UNIFI_TLS_SKIP_VERIFY=true # or TLS_CA_FILE, see TLS below
- DNSWEAVER_UNIFI_RECORD_TYPE=A
- DNSWEAVER_UNIFI_TARGET=192.168.1.100
- DNSWEAVER_UNIFI_DOMAINS=*.home.example.com
Configuration Reference¶
| Variable | Required | Default | Description |
|---|---|---|---|
TYPE |
Yes | - | Must be unifi |
URL |
Yes | - | Console base URL (https://192.168.1.1), with no path, query or fragment |
API_KEY |
Yes | - | Integration API key (sent as the X-API-KEY header) |
API_KEY_FILE |
Alt | - | Path to API key file (Docker secrets) |
SITE |
No | default |
Site internalReference (as shown in the console URL) or site UUID; letters, digits, - and _ only |
ZONE |
No | - | DNS zone for record filtering |
TTL |
No | 300 |
TTL for A, AAAA, and CNAME records (TXT and SRV have no TTL on UniFi) |
RECORD_TYPE |
Yes | - | A, AAAA, or CNAME |
TARGET |
Yes | - | Record value (IP or hostname) |
DOMAINS |
Yes | - | Glob patterns to match |
EXCLUDE_DOMAINS |
No | - | Patterns to exclude |
Record Types¶
A Records¶
Points hostnames to IPv4 addresses:
AAAA Records¶
Points hostnames to IPv6 addresses:
CNAME Records¶
Points hostnames to another hostname:
SRV and TXT Records¶
SRV records are created from workload labels (see Native Labels). UniFi stores SRV records as separate service, protocol, and domain fields, so the hostname must have the standard _service._proto.domain form, for example _minecraft._tcp.home.example.com.
TXT records are used for ownership tracking and are managed automatically.
Capabilities and Limitations¶
UniFi's Integration API supports TXT records, so dnsweaver uses its standard _dnsweaver.* ownership records here. Managed mode works fully: orphan cleanup only ever removes records dnsweaver created, and records you add by hand in the console are left alone.
| Feature | UniFi Network | Notes |
|---|---|---|
| A records | ✅ | |
| AAAA records | ✅ | |
| CNAME records | ✅ | |
| SRV records | ✅ | Hostname must be _service._proto.domain |
| TXT records | ✅ | Ownership tracking supported |
| Per-record TTL | ⚡ | A, AAAA, and CNAME only; TXT and SRV have no TTL on UniFi and report the instance TTL |
| Native update | ✅ | Records are replaced in place via PUT |
| Ownership tracking | ✅ | Standard _dnsweaver.* TXT records |
What dnsweaver will and won't touch
- Only policies the console marks as user-defined are managed. Entries the console derives from clients, devices, or other settings, and any policy with no reported origin, are never listed, updated or deleted, even in authoritative mode.
- Disabled policies are treated as absent: they are never listed, updated, or deleted. If you disable a dnsweaver-managed record in the console, dnsweaver sees it as missing and tries to create it again, which the console may reject as a duplicate. Delete the record, or remove the workload label, instead of disabling it.
MXandFORWARD_DOMAINpolicies are ignored.- Domain names are limited to 127 characters by the API.
TXT values and commas
The Integration API requires TXT text containing commas to be enclosed in double quotes. Every dnsweaver ownership value contains commas, so dnsweaver quotes on write and unquotes on read. You will see the quotes if you inspect the record in the console; that is expected. One value cannot be represented losslessly: TXT text that both contains a comma and is itself wrapped in double quotes. dnsweaver rejects that value with a clear error rather than storing it ambiguously.
Incomplete listings
Missing page fields, inconsistent offsets or counts, and missing or repeated policy IDs fail the listing. dnsweaver returns an error instead of using a partial record set. Reconciliation can resume when the controller returns a valid listing. These checks do not make offset pagination an atomic snapshot during concurrent changes.
Recommended Mode Configuration¶
# Default — managed mode with TXT ownership tracking
- DNSWEAVER_UNIFI_MODE=managed
# Write-only — no deletions
- DNSWEAVER_UNIFI_MODE=additive
# Full control — deletes any user-defined record in scope, use on a dedicated subdomain
- DNSWEAVER_UNIFI_MODE=authoritative
See Operational Modes for details on each mode.
Multiple Sites¶
Each provider instance targets one site. dnsweaver resolves SITE to the site's UUID when the instance starts, so two instances that name the same site differently (for example default and that site's UUID) are recognized as the same backend. To manage records on several sites of the same console, define one instance per site:
- DNSWEAVER_INSTANCES=unifi-main,unifi-branch
- DNSWEAVER_UNIFI_MAIN_TYPE=unifi
- DNSWEAVER_UNIFI_MAIN_URL=https://192.168.1.1
- DNSWEAVER_UNIFI_MAIN_API_KEY_FILE=/run/secrets/unifi_api_key
- DNSWEAVER_UNIFI_MAIN_SITE=default
- DNSWEAVER_UNIFI_MAIN_DOMAINS=*.home.example.com
- DNSWEAVER_UNIFI_MAIN_TARGET=192.168.1.100
- DNSWEAVER_UNIFI_BRANCH_TYPE=unifi
- DNSWEAVER_UNIFI_BRANCH_URL=https://192.168.1.1
- DNSWEAVER_UNIFI_BRANCH_API_KEY_FILE=/run/secrets/unifi_api_key
- DNSWEAVER_UNIFI_BRANCH_SITE=branch
- DNSWEAVER_UNIFI_BRANCH_DOMAINS=*.branch.example.com
- DNSWEAVER_UNIFI_BRANCH_TARGET=10.20.0.100
Docker Deployment¶
services:
dnsweaver:
image: maxamill/dnsweaver:latest
environment:
- DNSWEAVER_INSTANCES=unifi
- DNSWEAVER_UNIFI_TYPE=unifi
- DNSWEAVER_UNIFI_URL=https://192.168.1.1
- DNSWEAVER_UNIFI_API_KEY_FILE=/run/secrets/unifi_api_key
- DNSWEAVER_UNIFI_TLS_SKIP_VERIFY=true
- DNSWEAVER_UNIFI_MODE=managed
- DNSWEAVER_UNIFI_RECORD_TYPE=A
- DNSWEAVER_UNIFI_TARGET=192.168.1.100
- DNSWEAVER_UNIFI_DOMAINS=*.home.example.com
secrets:
- unifi_api_key
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
secrets:
unifi_api_key:
file: ./unifi_api_key.txt
TLS Configuration¶
UniFi consoles present a self-signed certificate by default. dnsweaver supports the unified TLS surface used by every HTTP provider:
| Env key | Purpose |
|---|---|
DNSWEAVER_UNIFI_TLS_CA_FILE |
Trust the console's certificate or a private CA bundle (PEM) |
DNSWEAVER_UNIFI_TLS_CERT_FILE / _TLS_KEY_FILE |
Present a client certificate (mTLS) |
DNSWEAVER_UNIFI_TLS_SERVER_NAME |
Override SNI / hostname verification |
DNSWEAVER_UNIFI_TLS_SKIP_VERIFY |
Disable verification (logs a warning at startup) |
DNSWEAVER_UNIFI_TLS_MIN_VERSION |
1.2 (default) or 1.3 |
Prefer TLS_CA_FILE where you can: export the console certificate once and mount it. TLS_SKIP_VERIFY=true is acceptable on a trusted management network. See the environment reference for complete recipes.
Mounted certs must be readable by uid/gid 1000
The container drops privileges to the unprivileged dnsweaver user, so a
client key mounted root:root 0600 yields permission denied. See
TLS Certificate File Permissions.
API Endpoints Used¶
For reference, dnsweaver uses these Integration API endpoints (relative to /proxy/network/integration/v1):
GET /info— connectivity and authentication checkGET /sites— resolveSITEto the site UUIDGET /sites/{siteId}/dns/policies— list records (paged, 200 per page)POST /sites/{siteId}/dns/policies— createPUT /sites/{siteId}/dns/policies/{id}— updateDELETE /sites/{siteId}/dns/policies/{id}— delete
Troubleshooting¶
Authentication Failed¶
Verify the key works with a direct API call:
A 401 means the key is wrong or was revoked. Keys are created under Settings → Control Plane → Integrations.
site "..." not found (available: default, ...)¶
SITE does not match any site the key can see. Use the internalReference shown in the error (it is also the segment right after /network/ in the console URL), or the site UUID.
404 on Every Request¶
The Integration API is not available at that URL. The most common cause is pointing at a standalone Network Application, which does not have the API (see the warning under Requirements). Check that URL is the console itself, not a reverse proxy that strips paths.
UniFi Network "..." is not supported; version 10.6 or later is required¶
The console reports a Network version older than 10.6, or one dnsweaver cannot parse. Update UniFi Network on the console.
Provider Stays Pending at Startup¶
dnsweaver looks up SITE when the instance starts. If the console cannot be reached, or SITE does not exist, the instance is reported as pending and retried with backoff (up to every 5 minutes) until the lookup succeeds. The error in the log says which of the two it is.
incomplete listing¶
The console returned a list of DNS policies that dnsweaver could not prove complete (for example, a page ended early, or the total changed while paging because someone edited records at the same moment). dnsweaver makes no changes for that instance on that pass and tries again on the next one. A persistent error points at the console or a proxy in front of it.
Records Exist but Names Do Not Resolve¶
Check that your clients use a UniFi gateway on the same site as their DNS server (see the warning under Requirements). The console stores records on sites without a gateway, but nothing answers queries for them.
Records Not Appearing¶
- Check that the domain matches your
DOMAINSpattern - Verify the record exists in the console under Settings → Policy Engine → Policy Table (filter by type DNS)
- If using
ZONEfiltering, ensure the domain ends with the zone suffix - Check the record is enabled; disabled records are treated as absent
SRV Record Rejected¶
UniFi requires SRV names in the form _service._proto.domain (for example _minecraft._tcp.home.example.com). Names without both underscore-prefixed labels are rejected before any API call.