signalapp/Signal-Server · error · IllegalArgumentException

target-queue-size-bytes must be positive

Error message

target-queue-size-bytes must be positive

What it means

TrimOversizedFoundationDbMessageQueuesCommand validates its tuning arguments at the start of crawlAccounts. target-queue-size-bytes is the byte threshold the trimmer shrinks queues toward; a zero or negative value is nonsensical, so an IllegalArgumentException is thrown before any accounts are processed.

Solutions

  1. Pass a positive byte value, e.g. --target-queue-size-bytes 100000
  2. Check the script/env that supplies the value resolves to a real positive number
  3. Remember target must also be strictly less than --max-queue-size-bytes

Example fix

// before
--target-queue-size-bytes 0
// after
--target-queue-size-bytes 100000
Defensive patterns

Strategy: validation

Validate before calling

long target = Long.parseLong(args["target-queue-size-bytes"]);
if (target <= 0) throw new IllegalArgumentException("target-queue-size-bytes must be positive");

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-oversized-foundation-db-message-queues` command with --target-queue-size-bytes of 0 or a negative number.

Common situations: Shell variable interpolation failing so the flag expands to 0/empty; copying an example command and leaving a placeholder value; unit confusion (passing a percentage instead of a byte count).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

        .type(Long.class)
        .dest(RANGE_SPLIT_CHUNK_SIZE_BYTES_ARGUMENT)
        .required(false)
        .setDefault(DEFAULT_RANGE_SPLIT_CHUNK_SIZE_BYTES)
        .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(

View on GitHub (pinned to 100ab61c82)