Skip to main content

May 2026 Releases

This page archives releases published in May 2026.

2026-05

v1.1.4

Release Scope

  • Patch Release reducing memory footprint and reload cost on the provider and rule-matching paths, plus WebUI fixes for mobile config-editor and plugin-filter usability, query-recorder chart labels, and self-hosting the Monaco editor. Also adds a "Migrate from mosdns" guide. This release introduces no breaking configuration changes and leaves the query hot path unchanged.

Changes

  • The client_ip / resp_ip / ptr_ip inline IP matchers now compile via finalize_compact, so compiled matchers no longer retain a duplicate copy of the source IP ranges (ip_set / geoip already did this).
  • finalize_compact now moves the merged IPv6 ranges into the compiled matcher instead of cloning them.
  • geoip feeds CIDR bytes straight into the matcher via add_v4_network / add_v6_network, skipping the per-entry String format + reparse round trip and speeding up load and reload.
  • adguard_rule badfilter resolution uses a HashSet built once instead of an O(n²) rescan that reallocated the cache key on every comparison.
  • Fixed the WebUI config editor and plugin filters being unusable on mobile.
  • Fixed Top-N labels being truncated in the WebUI query-recorder charts.
  • The WebUI Monaco editor is now self-hosted instead of loaded from the jsdelivr CDN, working in offline or restricted-network environments.
  • Docs: added a "Migrate from mosdns" guide.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.1.4; no crates/ workspace crate changed, so none need a version bump; release tag should use v1.1.4.
  • v1.1.3 configs upgrade directly to v1.1.4 with no new required fields.
  • The provider / matcher optimizations are internal implementation changes; they do not alter matching semantics or the query hot path and require no config changes.
  • Deployments using the WebUI config editor in restricted or offline networks benefit from the self-hosted Monaco editor and no longer need external CDN access.

v1.1.3

Release Scope

  • Patch Release fixing a Linux nftset interval-set ADD/DEL that was rejected by real kernels with EINVAL, an ipset byte-order bug in hashsize / maxelem, and a WebUI query_recorder tabs overflow. Also adds an upfront notice on the black_hole plugin documentation describing an upcoming behavior redesign. This release does not introduce breaking configuration changes.

Changes

  • Fixed nftset ADD / DEL / TEST encoding on interval sets: ADD / DEL now send the two-element list form nft userspace uses, resolving the EINVAL rejection observed on real kernels (issue #127); TEST sends only the start key and lets the kernel's interval tree resolve containment. Also fixed the per-element timeout byte order and relaxed dump parsing to tolerate unpaired INTERVAL_END anchors.
  • Fixed ipset create writing hashsize / maxelem in native byte order: on little-endian hosts the kernel would read hashsize=2048 as 524288. Also removed the stray IPSET_ATTR_LINENO=0 nested attribute, aligning with libipset.
  • Significantly expanded ripset wire-format unit and ipset integration test coverage.
  • Fixed a vertical overflow in the WebUI query_recorder detail panel tabs list.
  • Docs: added a prominent notice to the black_hole executor section announcing the upcoming mode field (nxdomain / nodata / null / custom / refused) that will cover every qtype, and explaining the motivation; current behavior is unchanged.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.1.3; oxidns-ripset bumped to 0.1.2; release tag should use v1.1.3.
  • v1.1.2 configs upgrade directly to v1.1.3 with no new required fields.
  • Linux deployments using the nftset plugin against flags interval sets should upgrade promptly; without this fix, ADD / DEL is rejected by real kernels with EINVAL.
  • Linux deployments that let OxiDNS create ipset sets with explicit hashsize / maxelem should upgrade; sets pre-created by the external ipset CLI are unaffected by this fix.
  • black_hole behavior is unchanged in this release, but the upcoming semantic redesign is worth tracking. For domain-level blocking today, prefer configuring both IPv4 and IPv6 fallback addresses (e.g. black_hole 0.0.0.0 :: short_circuit) or use reject 3.

v1.1.2

Release Scope

  • Patch Release fixing a Linux nftset write failure on flags interval sets, repairing the Windows service installer, and polishing systemd working-directory semantics, the WebUI run log viewer, and query_recorder ranking views. This release does not introduce breaking configuration changes.

Changes

  • Fixed nftset decoding set flags with native byte order, which left is_interval always false on little-endian hosts and caused every CIDR add against a flags interval set to fail with Unsupported entry for set type. Flags are now decoded as big-endian, with a byte-order regression test.
  • The nftset writer now processes each prefix independently, treats IpSetError::ElementExists as a skipped no-op, and aggregates ok / skipped / failed counts into a structured warn log instead of disabling the plugin on a single EEXIST.
  • Fixed the packaged Debian systemd unit failing pre-start because of an unwritable WorkingDirectory; runtime-relative paths (including WebUI assets) now use -d/--working-dir as the single base.
  • Fixed Windows install/uninstall scripts: reworked service management, binary path handling, and uninstall ordering to avoid orphaned processes or stale paths.
  • WebUI run log viewer adds a wrap toggle, and LogEntry.timestamp now carries millisecond precision so the UI can show local HH:MM:SS.mmm alongside the existing T+elapsed column for easier correlation with external timelines.
  • WebUI JSON responses and query_recorder SSE streams now tolerate non-JSON errors, heartbeat frames, empty payloads, and malformed events, so transient network hiccups no longer surface console errors.
  • query_recorder removes the fixed 200-row cap on top-client, top-qname, and slow-query stats endpoints; the WebUI rankings and slow-query list gain a “load more” control to navigate larger result sets.
  • WebUI plugin field documentation is resynced with the Rust plugin configuration.
  • Documentation site adds a Hero component, refreshes installation steps and the Docker run command, and adds multi-platform quickstart guidance; also documents the Debian /etc/oxidns and /var/lib/oxidns layout, WebUI symlink behavior, and client_ip troubleshooting.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.1.2; oxidns-ripset bumped to 0.1.1; release tag should use v1.1.2.
  • v1.1.1 configs upgrade directly to v1.1.2 with no new required fields.
  • Linux deployments using the nftset plugin against flags interval sets should upgrade promptly; without this fix, those sets cannot accept any add on little-endian architectures.
  • Deb-package upgrades no longer set systemd WorkingDirectory. If you relied on that value to resolve relative paths, set -d/--working-dir explicitly instead.
  • Clients of query_recorder ranking APIs can now request larger limit values; existing 200-row responses parse unchanged, so behavior remains compatible.

v1.1.1

Release Scope

  • Patch Release adding query_recorder history clearing and tightening the WebUI plugin-deletion workflow. This release does not introduce breaking configuration changes.

Changes

  • Added DELETE /api/plugins/<tag>/records for query_recorder, clearing persisted query records, execution-path steps, and the in-memory tail after flushing the background write queue. The response reports cleared_records.
  • Added a “Clear history” action to the WebUI query records panel with a confirmation dialog, clearing-state feedback, and automatic refresh of records, selected detail, and plugin-hit stats after completion.
  • Polished the WebUI plugin delete dialog: wider dependency-impact layout, wrapping for long fields, and clearer source / expected-target / removal-blocker details.
  • Fixed delete-dialog cancellation bubbling into plugin cards and opening the plugin detail sheet.
  • Fixed “repair in editor” removing the plugin before the user edits config; it now only switches to the editor for manual reference handling.
  • Fixed delete icons becoming permanently visible and unclickable when config validation errors are present; the dialog can now open and show the error reason.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.1.1; release tag should use v1.1.1.
  • v1.1.0 configs upgrade directly to v1.1.1 with no new required fields.
  • query_recorder history clearing is optional and does not affect existing record capture, retention cleanup, or stats query behavior.
  • Clearing history is irreversible and removes persisted query records plus path events for the selected recorder; on production systems, confirm the audit data is no longer needed before using it.

v1.1.0

Release Scope

  • Minor Release focused on safer configuration loading, upgrade and restart handling, query_recorder analytics, WebUI operations, and refreshed plugin documentation/navigation. This release includes a breaking upgrade configuration change; review related configs or automation before upgrading.

Breaking Change

  • upgrade restart configuration changed from enum-style restart: none|service and CLI --restart <none|service> to boolean no_restart: true and --no-restart.
  • The default behavior changed as well: successful upgrade apply now restarts the service automatically. To keep the old “do not restart after upgrade” behavior, explicitly set no_restart: true or pass --no-restart.

Changes

  • Configuration loading now supports YAML environment placeholders: ${VAR}, ${VAR:-default}, and $${...}. Expansion runs during startup, oxidns check, management API validation, and save-time validation, includes include paths, and reports missing variables or syntax errors with variable name, line, and column.
  • Reworked upgrade apply into a cross-platform flow. Windows now supports .zip archive extraction, binary replacement, and WebUI directory upgrades; zip extraction rejects unsafe paths to prevent zip-slip.
  • Added GitHub token support for upgrades, useful for higher API rate limits or private repositories. CLI uses --github-token; plugin configuration uses github_token.
  • Successful upgrades now restart by default. CLI upgrades restart the installed service through the platform service manager, while plugin-triggered upgrades request a graceful in-process restart that loads the new binary. To skip restart, use CLI --no-restart or plugin config no_restart: true.
  • Added management control POST /restart. On Unix the process restarts in place with exec; on Windows service deployments it cooperates with SCM restart behavior. OxiDNS also captures the original executable path before binary replacement so Linux restarts do not fail on /proc/self/exe (deleted).
  • query_recorder gained aggregate stats APIs and WebUI charts: top clients, top qnames, qtype / rcode distributions, latency histogram, slow-query ranking, and minute/hour query trends. SQLite read/write settings were tuned for these aggregation queries.
  • WebUI config lifecycle is clearer: top-level runtime / api / log changes now prompt for restart instead of hot reload; config rollback chooses hot reload or restart based on the changed fields, and restart progress is shown while the console waits for reconnection.
  • WebUI plugin management now checks references before deletion, can replace references, remove safely removable references, or jump to the editor for manual repair. Plugin renames update references and ask for confirmation when other plugins are affected.
  • Documentation refreshed the plugin overview and sidebar navigation, added the roadmap page, and clarified redirect rule forms, qname / cname domain rules, README roadmap, and disclaimers.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.1.0; release tag should use v1.1.0.
  • v1.0.2 DNS resolution configs generally upgrade directly to v1.1.0; environment placeholders are additive and do not affect configs that do not use them.
  • Breaking Change: old restart: none|service and CLI --restart <none|service> are no longer accepted. Use no_restart: true / --no-restart instead. To preserve the old “do not restart after upgrade” behavior, set no_restart: true or pass --no-restart.
  • Missing ${VAR} placeholders now fail config parsing. Use $${...} for literal ${...}, and quote placeholders when environment values may contain YAML-special characters.
  • New github_token / --github-token support is optional and does not affect existing public-repository upgrade configs.
  • Existing query_recorder deployments can use the new stats APIs and WebUI charts without config changes. The stats endpoints read SQLite history, so large databases should be monitored for disk and query latency.

v1.0.2

Release Scope

  • Patch Release fixing domain-based upstreams depending on local DNS during startup and config validation, and clarifying bootstrap versus dial_addr resolution precedence.

Changes

  • Fixed forward address validation reusing full ConnectionInfo construction. Domain-based upstreams now perform syntax validation only and no longer trigger system DNS resolution during startup validation.
  • Changed upstream connection-info construction so only literal IPs and explicit dial_addr values become startup-known remote IPs; hostnames remain as server_name and are resolved later through bootstrap or at first connection time.
  • Clarified the runtime mutual exclusion between dial_addr and bootstrap: when both are configured, dial_addr takes precedence, bootstrap is ignored, and initialization emits a warning.
  • Updated forward plugin reference docs and WebUI field descriptions with hostname resolution timing, the bootstrap / dial_addr either-or recommendation, and precedence behavior.
  • Added regression coverage for deferring domain upstream resolution, preserving the SNI hostname with dial_addr, and dial_addr overriding bootstrap.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.0.2; release tag should use v1.0.2.
  • v1.0.1 configs upgrade directly to v1.0.2 with no new required fields.
  • Domain-based upstreams without bootstrap or dial_addr no longer block startup; the first connection still uses the operating system resolver.
  • To avoid runtime dependence on local DNS entirely, configure exactly one of bootstrap or dial_addr for domain-based upstreams.
  • Existing configs that set both bootstrap and dial_addr still start, but only dial_addr is effective.

v1.0.1

Release Scope

  • Patch Release fixing DNS response compliance issues, client-IP canonicalization, and WebUI usability problems from v1.0.0, while adding service management capabilities, installer scripts, and query-auditing UX improvements.

Changes

  • Fixed redirect plugin placing synthetic CNAME records after other answers instead of first, aligning with RFC expectations.
  • Fixed dual-stack sockets passing IPv4-mapped IPv6 addresses (::ffff:x.x.x.x) into DnsContext without canonicalization, causing client_ip matchers and other IP-dependent logic to misidentify them as IPv6.
  • Fixed WebUI returning 404 on page refresh and added auto-connect to /api on first load for full-backend-hosting deployments.
  • Added service restart CLI command for restarting OxiDNS when running as a system service.
  • Added Linux / macOS / Windows hosted-service installer scripts (install.sh / install.ps1) for one-command install, registration, and service startup.
  • query_recorder panel gained click-to-filter by matcher row, color-coded latency badges, and Info tooltips on record-count column headers.
  • WebUI plugin detail sheets, cache dialogs, and config field editor polished: replaced native confirm with shadcn AlertDialog, adopted responsive two-column grid layout, and constrained content to max-w-6xl centered layout.

Compatibility and Upgrade Notes

  • Root crate version bumped to 1.0.1; release tag should use v1.0.1.
  • v1.0.0 configs upgrade directly to v1.0.1 with no new required fields.
  • Deployments using dual-stack sockets with client_ip matchers, ECS, or IP-dependent policies will see client IPs correctly canonicalized to IPv4 after upgrading.
  • Installer scripts register the app as a system service by default; set OXIDNS_INSTALL_SERVICE=0 for portable-only installation.

v1.0.0

Release Scope

  • Major Release marking OxiDNS's move from an experimental plugin-driven DNS engine to the 1.0 stable line. v1.0.0 officially includes the built-in WebUI management console and management API, plugin runtime, observability, packaging, and stability work since v0.5.2.

Important Upgrade Notice

  • This release completes the project rename to OxiDNS. The GitHub repository, release assets, binary name, package metadata, service files, README files, docs site, logo, and startup banner now use oxidns.
  • Older automatic upgrade flows still point at the pre-rename project and release assets, so they cannot upgrade directly to v1.0.0. When upgrading from an older build, manually download the matching OxiDNS release package, replace the binary, and deploy the bundled WebUI static assets.
  • After this one-time manual migration, future upgrades should use the new svenshi/oxidns repository and oxidns-* release assets.

WebUI Capabilities

  • OxiDNS WebUI brings runtime status, configuration, plugins, metrics, logs, query auditing, and cache management into one console, reducing day-to-day reliance on scattered CLI commands, log files, and handwritten API calls.
  • Configuration management is safer for production use: YAML editing, live validation, config history, diff review, apply, and rollback live in one workflow, so complex policy changes can be reviewed before they take effect and recovered more easily.
  • Plugin orchestration is easier to understand: plugin topology, plugin details, structured configuration, and the sequence composer make the DNS request path visible and reduce YAML reference mistakes, missing dependencies, and troubleshooting time.
  • Troubleshooting is more direct: metrics, live logs, query records, execution flow, and cache details can be inspected together, making it easier to trace a problematic domain to matched rules, upstream behavior, cache state, and final responses.
  • Deployment and access are simpler: the WebUI ships with release archives, Docker images, Debian packages, and the upgrade flow, and OxiDNS can host the static assets directly from the management API so one process serves both the API and the console.

Changes

  • Reworked the management API into a prefixed unified entry point, adding auth/CORS support, runtime state, log streaming, metrics, config save/apply/rollback, and plugin API aggregation.
  • Replaced the mutable global plugin registry with an immutable catalog plus runtime manager, simplified plugin factory creation context, hardened reload paths, and split registry internals into catalog, context, init_plan, and runtime modules.
  • Added a shared plugin metrics layer covering servers, forward upstreams, cache, query recorder, and side-effect executors, with unified management API exposure.
  • Expanded query_recorder with sampled matcher-hit stats, filtering, execution-flow visualization, record details, and cleaned-up model/store structures.
  • Added cache management APIs for reading cached DNS response details, TTLs, hit metadata, record contents, and cache snapshots.
  • Updated upgrade, release, Docker, Debian packaging, systemd service files, and CI workflows for the OxiDNS 1.0 release path.
  • Completed the project branding migration from ForgeDNS to OxiDNS across GitHub templates and all user-facing project identity.
  • Performance and stability work includes disabling Nagle on TCP upstreams, reducing split-lock pressure, moving dual-selector preferred probing out of forward, supporting dual-stack port-only listeners, and hardening global runtime-manager reloads.
  • Refreshed README, quickstart, configuration, API, plugin reference, scenarios, benchmarks, and MikroTik policy routing documentation.

Compatibility and Upgrade Notes

  • The root crate version is now 1.0.0; the release tag should be v1.0.0.
  • Existing v0.5.2 DNS resolution configs should generally upgrade directly. This release mainly introduces the complete WebUI, management API, metrics, and packaging capabilities.
  • When upgrading from pre-rename builds, do not rely on the old automatic upgrade flow to cross the rename boundary. Manually download the v1.0.0 release package and complete the migration.
  • The management API now uses a prefixed route layout. If reverse proxies, ACLs, or automation scripts call old API paths directly, confirm them against the updated API docs.
  • For automatic upgrade, Docker, or Debian package deployments, confirm that the console static asset directory and service files are installed with the new package.
  • Deployments relying on plugin reload, online config editing, or runtime APIs should validate auth, CORS, permissions, and rollback flows in a staging environment first.

v0.5.2

Release Scope

  • Patch Release focused on DoH / DoH3 upstream long-connection reuse and upstream duration parsing.

Changes

  • Fixed an issue where DoH (HTTP/2) and DoH3 (HTTP/3) upstream connection pools could reuse already closed connections. After the remote peer closes an idle connection, the pool now evicts unavailable connections and recreates fresh ones, avoiding repeated H2 send_request error or H3 send_request error failures (Closed #78).
  • Fixed upstream timeout configuration parsing. Values such as timeout: 3 and timeout: "3s" now deserialize correctly and can be used during forward plugin initialization (Closed #79).
  • Added unified duration parsing for duration-based fields, supporting units such as ms, s, m, h, and d. Bare numeric values are interpreted as seconds by default.

Compatibility and Upgrade Notes

  • This release does not introduce new required configuration fields. Existing v0.5.1 configurations can be upgraded directly.
  • Duration-based fields such as timeout and idle_timeout support formats including 3, "3", "3s", and "500ms".
  • Bare duration numbers are interpreted as seconds. Use an explicit ms suffix for millisecond-level values.
  • Upgrading to v0.5.2 is recommended for deployments that configure upstream timeout, or use DoH / DoH3 upstreams and have seen repeated request failures after long runtimes.

Back to the Release Notes index