{"record":{"id":"d74e59b77d6fcaa0","repo":"signalapp/Signal-Server","slug":"target-queue-size-bytes-must-be-less-than-max-queu","errorCode":null,"errorMessage":"target-queue-size-bytes must be less than max-queue-size-bytes","messagePattern":"target-queue-size-bytes must be less than max-queue-size-bytes","errorType":"console","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/workers/TrimOversizedFoundationDbMessageQueuesCommand.java","lineNumber":112,"sourceCode":"        .help(\"\"\"\n            The chunk size to use when determining split points for the range of keys covered by a message queue.\n            FoundationDB does not provide any documentation on this parameter, but observationally,\n            setting this value greater than 1 MB should be okay.\n            \"\"\");\n  }\n\n  @Override\n  protected void crawlAccounts(final Flux<Account> accounts) {\n    final long maxQueueSizeBytes = getNamespace().getLong(MAX_QUEUE_SIZE_BYTES_ARGUMENT);\n    final long targetQueueSizeBytes = getNamespace().getLong(TARGET_QUEUE_SIZE_BYTES_ARGUMENT);\n    final long rangeSplitChunkSizeBytes = getNamespace().getLong(RANGE_SPLIT_CHUNK_SIZE_BYTES_ARGUMENT);\n\n    if (targetQueueSizeBytes <= 0) {\n      throw new IllegalArgumentException(\"target-queue-size-bytes must be positive\");\n    }\n\n    if (targetQueueSizeBytes >= maxQueueSizeBytes) {\n      throw new IllegalArgumentException(\"target-queue-size-bytes must be less than max-queue-size-bytes\");\n    }\n\n    if (rangeSplitChunkSizeBytes <= 0) {\n      throw new IllegalArgumentException(\"range-split-chunk-size-bytes must be positive\");\n    }\n\n    final boolean dryRun = getNamespace().getBoolean(DRY_RUN_ARGUMENT);\n    final int maxConcurrency = getNamespace().getInt(MAX_CONCURRENCY_ARGUMENT);\n\n    final MessagesManager messagesManager = getCommandDependencies().messagesManager();\n\n    accounts\n        .flatMapIterable(account ->\n            account.getDevices().stream().map(\n                device -> new Pair<>(new AciServiceIdentifier(account.getAccountIdentifier()), device)).toList())\n        .doOnNext(_ -> Metrics.counter(QUEUES_INSPECTED_COUNTER_NAME, \"dryRun\", String.valueOf(dryRun)).increment())\n        .flatMap(accountAndDevice ->\n            messagesManager.trimQueue(accountAndDevice.first(), accountAndDevice.second(), maxQueueSizeBytes, targetQueueSizeBytes, rangeSplitChunkSizeBytes, dryRun),","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/workers/TrimOversizedFoundationDbMessageQueuesCommand.java#L94-L130","documentation":"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.","triggerScenarios":"Running the trim command where the --target-queue-size-bytes value is greater than or equal to --max-queue-size-bytes.","commonSituations":"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.","solutions":["Ensure --target-queue-size-bytes < --max-queue-size-bytes (e.g. target 100000, max 500000)","Audit the script that generates both flags for accidental swap","Re-run the command with corrected values"],"exampleFix":"// before\n--max-queue-size-bytes 100000 --target-queue-size-bytes 200000\n// after\n--max-queue-size-bytes 500000 --target-queue-size-bytes 100000","handlingStrategy":"validation","validationCode":"if (!(targetQueueSizeBytes < maxQueueSizeBytes)) {\n    throw new IllegalArgumentException(\"target must be < max\");\n}","typeGuard":null,"tryCatchPattern":"try { crawlAccounts(accounts); } catch (IllegalArgumentException e) { System.err.println(\"config: \" + e.getMessage()); System.exit(2); }","preventionTips":["Set target and max together in one place","Add a pre-run assertion target < max in runbooks","Avoid copy-pasting flag values between environments"],"tags":["cli","validation","configuration"],"backgroundTag":"conflicting-config-options","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}