Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for OpenTelemetry By James Joyner IV · · 9 min read

OpenTelemetry Error Guide: 'send_batch_max_size must be greater or equal to send_batch_size' — Fix Batch Processor Config

Quick answer

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
Free toolkit

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 batch processor.
  • 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_size is a small non-zero number below send_batch_size.
  • Every pipeline using that batch instance is down, not just one signal.
  • otelcol-contrib validate reproduces the same message.

Common Root Causes

  • Max set below targetsend_batch_size: 8192 with send_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_size as a byte cap; it counts items (spans, data points, log records), same as send_batch_size.
  • Templated values — a Helm/config-map render produced a max smaller than the injected size.
  • Named batch drift — a batch/large instance inherited a small max from a copied batch block.
  • 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_size must be 0 or >= send_batch_size.
  • When raising send_batch_size, update send_batch_max_size in the same edit.
  • Use 0 to mean “no upper bound” rather than picking an arbitrarily small number.
  • Ensure a full send_batch_max_size batch 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.

Free download · 368-page PDF

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.