Segment must be less than TotalSegments

TL;DR — In a parallel Scan, each worker sets Segment (its slice index) and TotalSegments (how many slices). DynamoDB requires 0 ≤ Segment < TotalSegments, and both must be supplied together. A Segment equal to or above TotalSegments is rejected. Assign each worker a distinct Segment from 0 to TotalSegments − 1.

What it means

ValidationException: The Segment parameter is zero-based and must be less than parameter TotalSegments: Segment: 5 is not less than TotalSegments: 2

# on DynamoDB Local the same call reports the constraint generically instead:
ValidationException: 1 validation error detected: Value '5' at 'segment' failed to satisfy constraint: Member must have value less than or equal to 1

A parallel scan divides the table into TotalSegments slices; each worker scans one slice identified by Segment. Valid Segment values are 0 through TotalSegments − 1. TotalSegments itself must be between 1 and 1,000,000. If you supply one without the other, or a Segment outside the range, DynamoDB rejects the call. It's an HTTP 400 ValidationException, client-side, and not retryable until the parameters are valid.

Why it happens

  • Off-by-one segment assignment — with TotalSegments = 4, using Segment values 1..4 instead of 0..3.
  • Segment ≥ TotalSegments — a worker index that meets or exceeds the slice count.
  • Only one of the pair supplied — passing Segment without TotalSegments (or vice-versa); both are required for a parallel scan.
  • A dynamic worker pool mismatchTotalSegments set to a different value than the number of workers actually launched, so some workers get out-of-range indices.

How to fix it

  1. Assign segments 0 to TotalSegments − 1 — one distinct Segment per worker.
  2. Always pass both parameters together on every parallel-scan request.
  3. Keep TotalSegments equal to the worker count and within 1..1,000,000 (a TotalSegments of 1 is just a sequential scan).
  4. Use zero-based indexing when mapping a worker's ordinal to its Segment.
  5. Log both parameters on every worker. When a fleet fails, the error message names the offending Segment and TotalSegments — compare them to what each process actually sent.

Example

const totalSegments = workers.length;
await Promise.all(
  workers.map((_, segment) =>
    doc.send(
      new ScanCommand({
        TableName: 'Orders',
        Segment: segment, // 0 .. totalSegments - 1
        TotalSegments: totalSegments
      })
    )
  )
);

In DynoTable

Before you parallelize a Scan in production, run a single-segment Scan in DynoTable to confirm the table and filter behave as expected. Open the table with ⌘K, run a Scan from the query panel, and inspect returned items — you see the data each segment would touch without launching a worker fleet.

When you move the Scan into code, prototype the request in the Query Builder — it emits Segment and TotalSegments alongside the full Scan parameters. Profile switching (⌘P) and Test Connection on Settings → Profiles keep workers pointed at the right account. See Connect to AWS and Install. Remember segments are zero-based: with four workers, valid values are 0, 1, 2, and 3 — not 1 through 4. Off-by-one segment assignment is the most common cause when worker count and TotalSegments match but one worker still fails.

Sources

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.