OpenTelemetry Error Guide: 'send_batch_max_size must be greater or equal to send_batch_size' — Fix Batch Processor Config
Fix 'send_batch_max_size must be greater or equal to send_batch_size' by setting the batch processor's max size to at least its send_batch_size.
- #opentelemetry
- #observability
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
The batch processor validates its own settings when the Collector loads. send_batch_size is the target number of items per batch; send_batch_max_size is a hard upper bound used to split oversized batches. If the max is set below the target — a non-zero value smaller than send_batch_size — the constraint is impossible to satisfy and the Collector aborts startup:
Error: failed to build pipelines: failed to create "batch" processor: send_batch_max_size must be greater or equal to send_batch_size
2026/07/12 11:07:44 collector server run finished with error: invalid configuration
The check exists because send_batch_max_size caps the size of an emitted batch: a max that is smaller than the target size would force the processor to violate one of the two limits on every flush.
The error means you set send_batch_max_size to a positive value that is less than send_batch_size; either raise the max to at least the target, or set it to 0 to disable the upper bound entirely.
Symptoms
- The Collector fails to build pipelines at startup and names the
batchprocessor. - Logs show
send_batch_max_size must be greater or equal to send_batch_size. - The failure started right after tuning batch sizes for throughput.
send_batch_max_sizeis a small non-zero number belowsend_batch_size.- Every pipeline using that
batchinstance is down, not just one signal. otelcol-contrib validatereproduces the same message.
Common Root Causes
- Max set below target —
send_batch_size: 8192withsend_batch_max_size: 2048, an obvious inversion. - Copy-paste mismatch — the target was raised for throughput but the max was left at an older, smaller value.
- Unit confusion — treating
send_batch_max_sizeas a byte cap; it counts items (spans, data points, log records), same assend_batch_size. - Templated values — a Helm/config-map render produced a max smaller than the injected size.
- Named batch drift — a
batch/largeinstance inherited a small max from a copiedbatchblock. - Intending “no cap” but using a small number — wanting unlimited batches but setting a low max instead of
0.
Diagnostic Workflow
Validate to confirm the batch processor is the culprit and see the exact constraint:
otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
journalctl -u otelcol-contrib --since '10 min ago' | grep -i 'send_batch_max_size'
Inspect the batch settings. Here the max is smaller than the target, which is invalid:
processors:
batch:
timeout: 5s
send_batch_size: 8192
send_batch_max_size: 2048 # WRONG: 2048 < 8192
Fix it by raising send_batch_max_size to at least send_batch_size (a common choice is equal, or a modest multiple to allow bursts to coalesce):
processors:
batch:
timeout: 5s
send_batch_size: 8192
send_batch_max_size: 8192 # CORRECT: max >= size
If you do not want an upper bound at all, set the max to 0, which disables splitting:
processors:
batch:
timeout: 5s
send_batch_size: 8192
send_batch_max_size: 0 # 0 = no maximum, batches are never split
Keep the max comfortably under your exporter’s message-size limit so a full batch still fits in one OTLP request:
# Confirm the receiver's accepted message size on the downstream Collector
grep -n 'max_recv_msg_size_mib' /etc/otelcol-contrib/config.yaml
Example Root Cause Analysis
To improve throughput, a team raised send_batch_size from 512 to 8192 on a gateway Collector but forgot the send_batch_max_size line still read 2048 from an earlier experiment. On restart the Collector failed to build pipelines with send_batch_max_size must be greater or equal to send_batch_size, and because both the traces and metrics pipelines shared that batch processor, the entire gateway stayed down and upstream agents’ sending queues began to back up.
The fix had two parts. First, send_batch_max_size was set to 8192 to match the new target size, satisfying the constraint; the team also confirmed 8192 spans fit under the downstream receiver’s max_recv_msg_size_mib, so raising the cap wouldn’t trade this error for a ResourceExhausted. Second, they added otelcol-contrib validate to the config rollout job, which evaluates the batch processor’s constraints and would have rejected the inverted values before deploy. The gateway restarted cleanly and drained the upstream queues within seconds.
Prevention Best Practices
- Keep the invariant in mind:
send_batch_max_sizemust be0or>= send_batch_size. - When raising
send_batch_size, updatesend_batch_max_sizein the same edit. - Use
0to mean “no upper bound” rather than picking an arbitrarily small number. - Ensure a full
send_batch_max_sizebatch still fits under the exporter/receiver message-size limit. - Remember both fields count items, not bytes — don’t set them from a byte budget.
- Validate configs in CI so an inverted pair fails the pull request, not the running Collector.
Quick Command Reference
# Validate config and surface the batch constraint
otelcol-contrib validate --config /etc/otelcol-contrib/config.yaml
# Watch the startup failure
journalctl -u otelcol-contrib --since '10 min ago' | grep -i 'send_batch_max_size'
# Check batch settings in the config
grep -nE 'send_batch_size|send_batch_max_size' /etc/otelcol-contrib/config.yaml
# Restart after correcting the sizes
systemctl restart otelcol-contrib
Conclusion
send_batch_max_size must be greater or equal to send_batch_size is a simple invariant violation in the batch processor: the upper bound can’t be smaller than the target batch size. Raise the max to at least the size, or set it to 0 to disable the cap — and keep a full batch under your exporter’s message-size limit. Validating configs in CI turns this into a caught error instead of a downed gateway.
Related
- OpenTelemetry Error Guide: ‘failed to parse config’
- OpenTelemetry Error Guide: ‘sending queue is full’
- OpenTelemetry Error Guide: ‘context deadline exceeded’
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.