2026-04-01
v10.33.0
Summary
New minimal configuration based installation packages
Counter views now show inline P95 histogram sparklines, category-based color coding, and Prometheus histogram percentile metrics
Health endpoint now includes a boot_id that changes on every restart
Radconf parse errors now point to the correct file and line when a block is left unclosed across multiple included files
The license block in the configuration is now optional
License changes can now be applied without restarting the server
Added systemd Type=notify readiness notification support
Added trace logging for low-level RADIUS packets and EAP messages
Log counter statistics now visually distinguish counter categories with colored counts and sparklines
Fix DNS-SD RadSec backend TLS certificate verification failure caused by trailing dot in SRV record hostnames and missing hostname for TLS server name
Fix DNS-SD RadSec backend incorrectly forwarding realm name as RADIUS query name, causing 'Unknown RADIUS query' errors on proxied requests
Fix log table displaying entries in wrong order when sorting by non-timestamp columns while streaming
Configuration ZIP import no longer preserves stale directories from the active configuration when the ZIP lacks them
License import now supports Ignore, Append, and Replace modes, matching the existing template import modes
Radiator now logs a startup warning and drops packets when a server references a policy name that is not defined
Fix variables set during inner EAP authentication (EAP-TTLS, PEAP) not being visible in the outer context
Inner EAP context errors are now propagated to the parent context
Added YubiKey OTP authentication support with cloud and offline validation paths
SQL statement bindings now support
radius.request.attrsfor storing all RADIUS request attributes as JSONRADIUS attribute log entries now include dictionary
typefieldAdded
tacacsplus.request.passwordexecution context variable for reading TACACS+ request passwordsFixed UI not refreshing sidebar and other data after deploying configuration with server restart
Fix map action match order with multivalue items
New minimal configuration based installation packages
Due to changes in the default configuration, the upgrade process for this package is not available. To change from older Radiator version to this new version a maintenance break is required.
Once installed, the existing configuration backup can be imported and taken back into use.
Instructions for the deb package
- Backup the existing configuration
- Remove existing installation with
apt-get remove --purge radiator-serverIf apt-get lists any directories as not removed, clear them out manually withrm -rf <directory> - Install new package with
apt install radiator-server - Restore the configuration from the backup
Instruction for the RPM package
- Backup the existing configuration
- Remove existing installation with
dnf remove radiator-serverIf apt-get lists any directories as not removed, clear them out manually withrm -rf <directory> - Install new package with
dnf install radiator-server - Restore the configuration from the backup
Richer counter views with inline histogram sparklines and category colors
The Management UI counter table and details pages have been significantly improved. Histograms are now first-class citizens throughout the UI and the Prometheus exporter.
Category-based color coding
Each counter row is now colored according to its semantic category:
- Success (green) — accepted requests, successful replies, cache hits
- Error (red) — processing errors, protocol failures, backend failures
- Warning (orange) — denied clients, timeouts, rejected requests
- Info (blue) — throughput metrics, active sessions
- Default (gray) — informational counters without explicit category
Categories can be inferred automatically from well-known counter names, or set
explicitly via register_counter_meta.
Inline histogram P95 sparklines
Histogram namespaces now render a compact P95 sparkline directly in the counter table, giving an at-a-glance view of latency history without navigating away from the table. Hovering the sparkline shows timestamps and the exact P95 value.
Rebuilt counter details page
The counter details page has been rebuilt on top of the unified clog tree API. Scalar counters display a bar chart, histograms display a latency chart with autoscaled Y-axis (µs → ms → s), and both share the same namespace sidebar.
System dashboard card
A new system dashboard card shows live memory usage, CPU utilisation, and AAA pipeline latency sparklines. Clicking the card opens the system counters view.
Prometheus histogram percentiles
The Prometheus exporter now publishes P50, P95, and P99 quantile gauges for
every histogram, grouped as radiator_histogram{unit_suffix} with
namespace, name, and quantile labels.
Clearer radconf error messages for unclosed blocks
When a radconf block (e.g. management { ... }) is left without a closing brace
and the configuration is split across multiple included files, the parse
error is now reported at the file and line containing the unclosed brace instead
of an unrelated file loaded after it.
The error message wording has also been improved: Unexpected EOF while reading
is now Unexpected end of file for clarity.
License block is now optional
The license block in the configuration file is now optional.
Existing configurations with an explicit license block continue to work
unchanged.
License changes are now applied on configuration reload without requiring a server restart.
See license configuration for details.
Systemd readiness notification
Radiator Server now supports the systemd Type=notify protocol. When running as a systemd service with Type=notify, Radiator sends a READY=1 notification after configuration has been loaded and all subsystems are initialized.
See Linux systemd support for details.
RADIUS packet and EAP message trace logging
Radiator Server now emits structured trace log entries for low-level RADIUS packets and EAP messages. This provides visibility into protocol-level details that are not captured by AAA authentication logs, including EAP negotiation exchanges and Status-Server packets.
See Log storage and formatting for details.
Color-coded log counter statistics
The Statistics page now color-codes log counters based on their category. Error counters are shown in red, warning counters in orange, success counters in green, and info counters in blue. The sparkline charts also use the corresponding color. Counters with the default category remain unstyled.
Configuration import improvements
When importing a configuration ZIP archive, directories that are enabled for
import but missing from the ZIP are no longer incorrectly preserved from the
active configuration. Previously, importing a ZIP without e.g. a tls/
directory would copy the active tls/ into the pending configuration, even
though the user intended to import from the ZIP. Now, the pending configuration
only contains what is in the ZIP (for enabled content types), and a warning is
shown when the ZIP lacks an expected directory.
License files now support the same three import modes as templates:
- Ignore (default) — preserve licenses from active configuration
- Append — merge licenses from the ZIP with existing licenses
- Replace — use only licenses from the ZIP, removing any existing licenses
The API accepts a new licenseImportMode query parameter with values ignore,
append, or replace.
See Configuration Import and Export for updated documentation.
Server with undefined policy reference now warns and drops packets
Previously, if a server's policy directive named a policy that was not defined
in the configuration, the server silently fell back to selecting the first
matching policy. This masked configuration errors and caused unexpected behavior.
Radiator now validates policy name references at startup. If a server's policy
directive names a policy that does not exist, a warning is logged at startup. At
request time, the packet is dropped and a debug log entry is emitted (upsampled
to a warning once per minute).
Note: the previous fallback behavior - where omitting the policy directive
causes Radiator to iterate policies in configuration file definition order and
use the first one with matching conditions and a matching handler - is unchanged.
See servers.policy for updated documentation.
Fix variable modifications in inner EAP context
Variables set or modified during inner EAP authentication (e.g. inside
eap-ttls or eap-peap blocks) are now immediately visible to the outer
authentication context after the EAP block completes.
Previously, the inner authentication context received a deep copy of the parent's variables. Any modifications made inside the inner context were lost once the inner authentication finished, because changes were never propagated back to the outer context.
Now the inner and outer contexts share the same variable storage, so a
modify vars.inner = "value" inside an EAP-TTLS @authentication block
can be read via vars.inner in the outer handler after the eap block.
Example
@authentication {
eap {
eap-ttls {
tls {
# ...
}
@authentication {
backend {
name "USERS";
query "FIND_USER";
}
pap;
# Copy the client certificate email to a variable
if any {
cert.subject_alt.email != none;
}
then {
modify vars.certemail = cert.subject_alt.email;
}
}
}
}
# vars.certemail is now available here — previously it was lost
# when the inner EAP context was discarded
assert "hello@example.com" vars.certemail;
}
Propagate inner EAP context errors to the parent context
Errors raised during inner EAP authentication are now propagated to the parent context when using EAP.
Previously, an error inside an inner EAP context could be handled only within that inner context. Now those errors are also visible to the parent context, which makes it easier to handle EAP failures consistently in outer authentication logic.
YubiKey OTP Authentication
Radiator now supports Yubico OTP authentication with two validation paths:
- Cloud validation — The
yubikeyHTTP backend forwards OTPs to an external Yubico KSM-compatible server (such asapi.yubico.com) with HMAC-SHA1 signed requests and verified responses. See the HTTP backend reference. - Offline validation — The
yubikeyaction decrypts and validates OTPs locally using a stored AES-128 key. No network call is made. See theyubikeyaction reference.
Both paths support two-factor authentication by combining a static password with the YubiKey OTP using the range parameter on the pap and yubikey actions.
For a complete walkthrough including backend schema, configuration examples, and replay protection, see the YubiKey Authentication article.
SQL bindings support for radius.request.attrs
The radius.request.attrs binding can now be used in SQL statement bindings to store all RADIUS request attributes as a flat JSON object into a database column. This works with SQLite, MySQL, and PostgreSQL backends.
Example configuration:
statement "STORE_ACCOUNTING" {
statement "INSERT INTO accounting (attrs) VALUES (?)";
bindings {
radius.request.attrs;
}
}
When stored through SQL backends, the attributes are serialized as a flat JSON object keyed by lowercase attribute name. Repeated attributes are stored as JSON arrays. Existing logging and trace output continues to use the JSON array format.
Dictionary type included in RADIUS attribute logs
RADIUS attribute entries in authentication and accounting log output now include a "type" field that shows the dictionary datatype of each attribute. The JSON array format used in logging and tracing changed from {"name": "...", "value": ...} to {"name": "...", "type": "...", "value": ...}.
The type value is the dictionary datatype string such as "string", "enum32", "ipv4addr", etc. For unknown attributes that are not found in the dictionary, the type is null.
Example log entry:
{"name": "user-name", "type": "string", "value": "mikem"}
{"name": "service-type", "type": "enum32", "value": "framed-user"}
{"name": "26.99999.1", "type": null, "value": "deadbeef"}
Added tacacsplus.request.password context variable
A new read-only execution context variable tacacsplus.request.password is now
available for TACACS+ authentication processing. This allows accessing the
password from incoming TACACS+ authentication requests as a masked password
value.
This enables LDAP bind authentication for TACACS+ by passing the request password directly to an LDAP bind query:
backends {
ldap "LDAP" {
bind "BIND_USER" {
dn vars.dn;
password tacacsplus.request.password;
}
}
}
See Execution Context for the full list of available TACACS+ context variables.