signalapp/Signal-Server · error · IllegalArgumentException

target-queue-size-bytes must be less than…

Error message

target-queue-size-bytes must be less than max-queue-size-bytes

What it means

The trim command requires target-queue-size-bytes to be strictly less than max-queue-size-bytes; otherwise there is no trimming to perform (queues above max would already be under target). crawlAccounts throws IllegalArgumentException to fail fast on this contradictory configuration.

Solutions

  1. Ensure --target-queue-size-bytes < --max-queue-size-bytes (e.g. target 100000, max 500000)
  2. Audit the script that generates both flags for accidental swap
  3. Re-run the command with corrected values

Example fix

// before
--max-queue-size-bytes 100000 --target-queue-size-bytes 200000
// after
--max-queue-size-bytes 500000 --target-queue-size-bytes 100000
Defensive patterns

Strategy: validation

Validate before calling

if (!(targetQueueSizeBytes < maxQueueSizeBytes)) {
    throw new IllegalArgumentException("target must be < max");
}

Try / catch

try { crawlAccounts(accounts); } catch (IllegalArgumentException e) { System.err.println("config: " + e.getMessage()); System.exit(2); }

Prevention

When it happens

Trigger: Running the trim command where the --target-queue-size-bytes value is greater than or equal to --max-queue-size-bytes.

Common situations: Swapping the two flag values by mistake; adjusting one value in a script without adjusting the other; copy-paste of a config where values were inverted.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/d74e59b77d6fcaa0. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/workers/TrimOversizedFoundationDbMessageQueuesCommand.java:112

        .help("""
            The chunk size to use when determining split points for the range of keys covered by a message queue.
            FoundationDB does not provide any documentation on this parameter, but observationally,
            setting this value greater than 1 MB should be okay.
            """);
  }

  @Override
  protected void crawlAccounts(final Flux<Account> accounts) {
    final long maxQueueSizeBytes = getNamespace().getLong(MAX_QUEUE_SIZE_BYTES_ARGUMENT);
    final long targetQueueSizeBytes = getNamespace().getLong(TARGET_QUEUE_SIZE_BYTES_ARGUMENT);
    final long rangeSplitChunkSizeBytes = getNamespace().getLong(RANGE_SPLIT_CHUNK_SIZE_BYTES_ARGUMENT);

    if (targetQueueSizeBytes <= 0) {
      throw new IllegalArgumentException("target-queue-size-bytes must be positive");
    }

    if (targetQueueSizeBytes >= maxQueueSizeBytes) {
      throw new IllegalArgumentException("target-queue-size-bytes must be less than max-queue-size-bytes");
    }

    if (rangeSplitChunkSizeBytes <= 0) {
      throw new IllegalArgumentException("range-split-chunk-size-bytes must be positive");
    }

    final boolean dryRun = getNamespace().getBoolean(DRY_RUN_ARGUMENT);
    final int maxConcurrency = getNamespace().getInt(MAX_CONCURRENCY_ARGUMENT);

    final MessagesManager messagesManager = getCommandDependencies().messagesManager();

    accounts
        .flatMapIterable(account ->
            account.getDevices().stream().map(
                device -> new Pair<>(new AciServiceIdentifier(account.getAccountIdentifier()), device)).toList())
        .doOnNext(_ -> Metrics.counter(QUEUES_INSPECTED_COUNTER_NAME, "dryRun", String.valueOf(dryRun)).increment())
        .flatMap(accountAndDevice ->
            messagesManager.trimQueue(accountAndDevice.first(), accountAndDevice.second(), maxQueueSizeBytes, targetQueueSizeBytes, rangeSplitChunkSizeBytes, dryRun),

View on GitHub (pinned to 100ab61c82)