vectordotdev/vector · error · BuildError
The drain_timeout_ms ({}) must be less than session_timeout_
Error message
The drain_timeout_ms ({}) must be less than session_timeout_ms ({}) What it means
The Kafka source validates that an explicit `drain_timeout_ms` (how long the source waits to flush pending acknowledgements on shutdown) does not exceed `session_timeout_ms`. If it does, `InvalidDrainTimeoutSnafu` fails the source build: draining longer than the consumer session timeout would be pointless because the broker evicts the consumer from the group first. Note the check is `<=`, so equal values are allowed; the default drain timeout is half of `session_timeout_ms` (10s default → 5s).
Source
Thrown at src/sources/kafka.rs:347
#[async_trait::async_trait]
#[typetag::serde(name = "kafka")]
impl SourceConfig for KafkaSourceConfig {
async fn build(&self, cx: SourceContext) -> crate::Result<super::Source> {
let log_namespace = cx.log_namespace(self.log_namespace);
let decoder =
DecodingConfig::new(self.framing.clone(), self.decoding.clone(), log_namespace)
.build()?;
let decompressor = self
.decompression
.as_ref()
.map(DecompressionConfig::build)
.transpose()?;
let acknowledgements = cx.do_acknowledgements(self.acknowledgements);
if let Some(d) = self.drain_timeout_ms {
snafu::ensure!(
Duration::from_millis(d) <= self.session_timeout_ms,
InvalidDrainTimeoutSnafu {
value: d,
session_timeout_ms: self.session_timeout_ms
}
);
}
let (consumer, callback_rx) = create_consumer(self, acknowledgements)?;
Ok(Box::pin(kafka_source(
self.clone(),
consumer,
callback_rx,
decoder,
decompressor,
cx.out,
cx.shutdown,View on GitHub (pinned to 3708c39b12)
Solutions
- Set `drain_timeout_ms` to a value ≤ `session_timeout_ms` (or just remove it — the default is half the session timeout).
- If a longer drain is genuinely needed, raise `session_timeout_ms` first, then set `drain_timeout_ms` under it (mind broker `group.max.session.timeout.ms`).
- Re-run `vector validate <config>` to confirm the constraint passes before deploy.
Example fix
# before
sources:
kafka_in:
type: kafka
session_timeout_ms: 6000
drain_timeout_ms: 15000
# after
sources:
kafka_in:
type: kafka
session_timeout_ms: 6000
drain_timeout_ms: 5000 Defensive patterns
Strategy: validation
Validate before calling
# Pre-deploy check (or `vector validate`):
python3 - <<'EOF'
import yaml, sys
cfg = yaml.safe_load(open("vector.yaml"))
for s in (cfg.get("sources") or {}).values():
if s.get("type") == "kafka":
d, sess = s.get("drain_timeout_ms"), s.get("session_timeout_ms", 10000)
if d is not None and d > sess:
sys.exit(f"drain_timeout_ms {d} > session_timeout_ms {sess}")
EOF Prevention
- Omit drain_timeout_ms and accept the safe default (half of session_timeout_ms).
- When tuning either knob, tune them as a pair; keep drain ≤ session.
- Run `vector validate` in CI for every config change.
When it happens
Trigger: Setting `drain_timeout_ms` in a `kafka` source config to a value greater than `session_timeout_ms` (default 10000). Example: `session_timeout_ms: 6000` with `drain_timeout_ms: 15000` fails at config build time, before any broker connection.
Common situations: Operators raising drain timeout for graceful shutdown without touching session timeout; lowering `session_timeout_ms` for faster rebalancing while keeping an old large `drain_timeout_ms`; copying drain settings between sources with different session timeouts.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Partition consumer finished after completion.
- Partition assignment received after completion.
- Partitions revoked after completion.
- Shutdown received after completion.
- Drain deadline received after completion.
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/9a45e9a3369df53f.
Report an issue: GitHub.