vectordotdev/vector · error
unknown output
Error message
unknown output
What it means
`send_batch_named` looks up the requested output name in `self.named_outputs` and panics with "unknown output" via `.expect()` when the name is not registered. Named outputs must first be created with `add_output`; the library treats sending to an unregistered name as a programming error rather than a recoverable condition.
Solutions
- Call `add_output(name, output)` (or register the output in the source's `Output` definition) before sending to that name.
- Verify the name string in `send_batch_named` exactly matches the registered output name — check for typos and casing.
- Confirm you are using the same `SourceSender` instance that had the output registered.
- If the name is dynamic, validate it against the registered output set before sending instead of letting it panic.
Example fix
// before
sender.send_batch_named("outb", events).await?; // panics if not added
// after
let recv = sender.add_output("outb", Output::default());
sender.send_batch_named("outb", events).await?; Defensive patterns
Strategy: validation
Validate before calling
// Check the name is registered before sending (at source setup time) let registered: Vec<&str> = vec!["stdout", "errors"]; // names passed to add_output assert!(registered.contains(&"stdout"), "output 'stdout' not registered via add_output");
Type guard
fn output_exists(sender: &SourceSender, name: &str) -> bool {
// if named_outputs is private, mirror registration in your own registry:
registered_outputs().iter().any(|n| n == name)
} Try / catch
// Panics are not catchable normally; validate instead, or isolate:
let ok = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
futures::executor::block_on(sender.send_batch_named(name, events))
}));
if ok.is_err() { /* unknown output name: fix registration */ } Prevention
- Define output names as constants shared between add_output and send_batch_named call sites.
- Register every named output during source build() before any send can occur.
- Never build output name strings dynamically from config without validating against the registered set.
- Rename outputs with compiler-checked constants, not raw string literals.
When it happens
Trigger: Calling `sender.send_batch_named(name, events)` with a name that was never passed to `add_output` on that same `SourceSender` instance — typically a typo, a renamed output, or sending on a different sender than the one configured.
Common situations: Custom sources that declare named outputs in one place but send under a slightly different name; refactors renaming outputs without updating send calls; configs referencing output names the source never registers (e.g. removed or conditionally-added outputs).
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- no default output
- can't run runner twice
- Couldn't broadcast config changes.
- Encountered a connection-time error during runtime
- error creating request
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/826fe683ddac26c0.
Report an issue: GitHub.
Appendix: source
Thrown at lib/vector-core/src/source_sender/sender.rs:291
E: Into<Event> + ByteSizeOf,
I: IntoIterator<Item = E>,
<I as IntoIterator>::IntoIter: ExactSizeIterator,
{
self.default_output_mut().send_batch(events).await
}
/// Send a batch of events event to a named output.
///
/// This internally handles emitting [EventsSent] and [ComponentEventsDropped] events.
pub async fn send_batch_named<I, E>(&mut self, name: &str, events: I) -> Result<(), SendError>
where
E: Into<Event> + ByteSizeOf,
I: IntoIterator<Item = E>,
<I as IntoIterator>::IntoIter: ExactSizeIterator,
{
self.named_outputs
.get_mut(name)
.expect("unknown output")
.send_batch(events)
.await
}
}
View on GitHub (pinned to bdb87aeaa4)