diff --git a/docs/build-plugins/register-behavior.mdx b/docs/build-plugins/register-behavior.mdx
index 1e37467a..d995ca77 100644
--- a/docs/build-plugins/register-behavior.mdx
+++ b/docs/build-plugins/register-behavior.mdx
@@ -25,82 +25,6 @@ That gives the plugin system three important guarantees:
Use the context only after validation succeeds. Validation should inspect config and return diagnostics; registration should create runtime objects and attach them to the context.
-## Activation APIs
-
-Use the plugin APIs in this order:
-
-1. Register the plugin kind.
-2. Build a `PluginConfig`.
-3. Validate the config.
-4. Initialize the config.
-5. Inspect the activation report.
-6. Clear active config during teardown when needed.
-
-
-
-```python
-import nemo_relay
-
-config = nemo_relay.plugin.PluginConfig()
-config.components = [
- nemo_relay.plugin.ComponentSpec(
- kind="header-plugin",
- config={"header_name": "x-tenant", "value": "tenant-a"},
- )
-]
-
-report = nemo_relay.plugin.validate(config)
-active_report = await nemo_relay.plugin.initialize(config)
-kinds = nemo_relay.plugin.list_kinds()
-nemo_relay.plugin.clear()
-```
-
-
-
-
-```ts
-import * as plugin from 'nemo-relay-node/plugin';
-
-const config = plugin.defaultConfig();
-config.components = [
- plugin.ComponentSpec(
- 'header-plugin',
- { header_name: 'x-tenant', value: 'tenant-a' },
- { enabled: true },
- ),
-];
-
-const report = plugin.validate(config);
-const activeReport = await plugin.initialize(config);
-const kinds = plugin.listKinds();
-plugin.clear();
-```
-
-
-
-
-```rust
-use nemo_relay::plugin::{
- clear_plugin_configuration, initialize_plugins, list_plugin_kinds, validate_plugin_config,
- PluginComponentSpec, PluginConfig,
-};
-
-let mut config = PluginConfig::default();
-let mut component = PluginComponentSpec::new("header-plugin");
-component.config.insert("header_name".into(), "x-tenant".into());
-component.config.insert("value".into(), "tenant-a".into());
-config.components.push(component);
-
-let report = validate_plugin_config(&config);
-let active_report = initialize_plugins(config).await?;
-let kinds = list_plugin_kinds();
-clear_plugin_configuration()?;
-```
-
-
-
-
-
## Header Plugin Example
The same model applies in every binding: validate component-local config, then install middleware through the component-scoped registration context.
@@ -257,6 +181,83 @@ register_plugin(Arc::new(HeaderPlugin))?;
+## Activation APIs
+
+With the plugin kind registered (see the Header Plugin Example above), use the plugin APIs in this order:
+
+1. Build a `PluginConfig`.
+2. Validate the config.
+3. Initialize the config.
+4. Inspect the activation report.
+5. Clear active config during teardown when needed.
+
+Register the plugin kind before you initialize. An unregistered kind is reported by `validate()` only as a warning under the default `unknown_component="warn"` policy, so an error-only check still passes, but `initialize()` raises for a kind that was never registered.
+
+
+
+```python
+import nemo_relay
+
+config = nemo_relay.plugin.PluginConfig()
+config.components = [
+ nemo_relay.plugin.ComponentSpec(
+ kind="header-plugin",
+ config={"header_name": "x-tenant", "value": "tenant-a"},
+ )
+]
+
+report = nemo_relay.plugin.validate(config)
+active_report = await nemo_relay.plugin.initialize(config)
+kinds = nemo_relay.plugin.list_kinds()
+nemo_relay.plugin.clear()
+```
+
+
+
+
+```ts
+import * as plugin from 'nemo-relay-node/plugin';
+
+const config = plugin.defaultConfig();
+config.components = [
+ plugin.ComponentSpec(
+ 'header-plugin',
+ { header_name: 'x-tenant', value: 'tenant-a' },
+ { enabled: true },
+ ),
+];
+
+const report = plugin.validate(config);
+const activeReport = await plugin.initialize(config);
+const kinds = plugin.listKinds();
+plugin.clear();
+```
+
+
+
+
+```rust
+use nemo_relay::plugin::{
+ clear_plugin_configuration, initialize_plugins, list_plugin_kinds, validate_plugin_config,
+ PluginComponentSpec, PluginConfig,
+};
+
+let mut config = PluginConfig::default();
+let mut component = PluginComponentSpec::new("header-plugin");
+component.config.insert("header_name".into(), "x-tenant".into());
+component.config.insert("value".into(), "tenant-a".into());
+config.components.push(component);
+
+let report = validate_plugin_config(&config);
+let active_report = initialize_plugins(config).await?;
+let kinds = list_plugin_kinds();
+clear_plugin_configuration()?;
+```
+
+
+
+
+
## Registration Checklist
Before publishing or sharing a plugin:
diff --git a/docs/build-plugins/validate-configuration.mdx b/docs/build-plugins/validate-configuration.mdx
index e59f8c30..f420768c 100644
--- a/docs/build-plugins/validate-configuration.mdx
+++ b/docs/build-plugins/validate-configuration.mdx
@@ -126,6 +126,14 @@ Prefer stable diagnostic codes over prose-only messages. The message can improve
Use the validation API before initialization and fail deployment if the report contains errors.
+
+This error check does not catch an unknown or unregistered component kind. Under
+the default `unknown_component="warn"` policy that case is reported as a warning,
+not an error, so the check below passes while `initialize()` still raises for a
+kind that is not registered. Register every kind before initialization, or set
+`unknown_component="error"` to make validation fail on unknown kinds.
+
+
```python