Rail Engine Support
The NVIDIA NeMo Guardrails library ships 33 built-in rails under nemoguardrails/library.
Each rail declares its behavior in a rail manifest, and each manifest exposes one or more surfaces.
A surface is the flow name you list under rails.input.flows, rails.output.flows, or rails.retrieval.flows in config.yml.
The 33 manifests declare 78 surfaces in total.
LLMRails runs all 78 through its Colang runtime, in both Colang 1.0 and Colang 2.x.
IORails runs 59 of them by compiling the manifest directly, without Colang.
This page lists every surface and the engine that can run it. For capability areas that are not tied to a specific rail, such as streaming, observability, and the generation API, refer to Engine Feature Support.
How to Read This Page
Legend: ✓ supported · ✗ not supported.
The Flow column is the exact string you put in config.yml.
The Notes column records either the conversation value the rail rewrites or the reason IORails cannot run it.
A ✓ in the IORails column means the surface is servable: nothing in its manifest contract puts it out of reach of the engine.
Whether a particular configuration actually runs it also depends on that configuration, because IORails validates models and optional dependencies at startup.
Refer to Configuration-Dependent Refusals.
Support Summary
The following table summarizes surface support by direction:
IORails does not accept a rails.retrieval section at all, so every retrieval surface is an LLMRails capability.
A configuration that declares one routes to LLMRails by default.
Refer to What Happens to an Unsupported Configuration.
Support Matrix
Input Surfaces
The following table lists the input surfaces:
Output Surfaces
The following table lists the output surfaces:
Retrieval Surfaces
Retrieval surfaces run against the knowledge-base chunks retrieved for a turn.
IORails has no retrieval pipeline, so all of them are LLMRails only:
Tool Surfaces
Tool rails are not manifest surfaces.
IORails registers them separately as local structural and schema validators that reach no model:
For configuration and behavior, refer to Tool Calling.
Why IORails Refuses a Surface
IORails derives its scope from the manifest rather than from a hardcoded list of rail names.
A surface is unsupported when the engine cannot satisfy its declared contract.
Adding a new rail to the catalog therefore needs no change in the engine.
Two of the per-surface reasons are structural and one is temporary:
The checks run in the order the table lists them and report the first reason that applies.
As a result, a retrieval surface that both rewrites and reads relevant_chunks is reported under the rewrite reason.
A third structural constraint applies to the configuration as a whole rather than to any one surface.
IORails accepts only the input, output, config, tool_input, and tool_output rail sections, so a configuration that declares rails.retrieval, rails.dialog, or any other section routes to LLMRails by default, regardless of which flows it names.
The engine checks that constraint first, so it does not report a per-surface reason for a retrieval flow.
IORails.unsupported_reason() reports the unsupported rail section and stops, so a configuration with a rails.retrieval section reports config has rails outside the IORails-supported set: ['retrieval'] rather than the rewrite or read reason its surfaces would give.
The reasons in the table above describe what each surface’s manifest declares, which is what the retrieval rows of the matrix record.
What Happens to an Unsupported Configuration
The Guardrails facade decides what an unsupported rail means for your application:
Every “routes to LLMRails” statement on this page and in the guardrail catalog describes the default.
Use require_iorails=True when you depend on an IORails-only capability such as OpenTelemetry metrics and would rather fail at startup than silently lose it.
Configuration-Dependent Refusals
Beyond the fixed matrix above, IORails validates two things per configuration when it compiles a rail at startup.
Where LLMRails does not, it reports the same problem at request time instead:
A flow that carries a $model= parameter is validated by RailsConfig rather than by an engine, so loading the configuration raises InvalidRailsConfigurationError on both engines.
The other two refusals come from the IORails compiler and raise RailCompilationError.
Through the Guardrails facade those two are fallback conditions: by default the configuration routes to LLMRails and the reason is logged.
The rails that declare an optional dependency are the following:
Hugging Face Classifier and Jailbreak Detection each offer an in-process backend and a remote endpoint.
IORails enforces the dependency only when the configuration selects the in-process backend.
The surfaces that bind a model type are the following:
RailsConfig reads the $model= parameter off the flow name, so it catches only the first three.
A manifest-fixed model type is invisible to that check, which is why the last three are an IORails-only refusal.
IORails never reaches the model check for patronus lynx check output hallucination, because the surface check refuses it first.
A manifest can also declare a model under requirements.models, as Self-Check and Hallucination Detection do for llm.
That declaration is descriptive metadata for the catalog.
Neither engine enforces it at startup, so a missing model surfaces when the rail runs.
Rail Behavior Differences
The manifest and the action are shared, so both engines reach the same allow, block, or transform decision. The following table shows how each engine acts on that decision:
One transform rule is shared rather than per-engine.
RailsConfig rejects a configuration that combines a rewriting output rail with output-rail streaming unless rails.output.streaming.stream_first is false and context_size is 0, because a rewrite cannot be applied to chunks that have already been sent.
That validation runs for both engines.
For the shared decision object that both engines read, refer to Rail Outcomes.
Checking Support Programmatically
Ask the engine whether it can serve a whole configuration:
Enumerate the surfaces the installed version declares:
Related Information
Use the following references for related concepts and configuration:
- Engine Feature Support compares the two engines on capabilities that are not rail-specific.
- Rail Manifests documents the manifest schema that this matrix is derived from.
- Guardrail Catalog documents each rail’s configuration and behavior.
- Rail Outcomes documents the allow, block, and transform decision that rail actions return.