{"record":{"id":"2f89fcace899b034","repo":"signalapp/Signal-Server","slug":"s3-object-too-large","errorCode":null,"errorMessage":"S3 object too large","messagePattern":"S3 object too large","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/s3/S3ObjectMonitor.java","lineNumber":154,"sourceCode":"   * @return the current version of the monitored S3 object.  Caller should close() this upon completion.\n   * @throws IOException if the retrieved S3 object is larger than the configured maximum size\n   */\n  @VisibleForTesting\n  ResponseInputStream<GetObjectResponse> getObject() throws IOException {\n    final ResponseInputStream<GetObjectResponse> response = s3Client.getObject(GetObjectRequest.builder()\n        .key(objectKey)\n        .bucket(s3Bucket)\n        .build());\n\n    lastETag.set(response.response().eTag());\n\n    if (response.response().contentLength() <= maxObjectSize) {\n      return response;\n    } else {\n      log.warn(\"Object at s3://{}/{} has a size of {} bytes, which exceeds the maximum allowed size of {} bytes\",\n          s3Bucket, objectKey, response.response().contentLength(), maxObjectSize);\n      response.abort();\n      throw new IOException(\"S3 object too large\");\n    }\n  }\n\n  /**\n   * Polls S3 for object metadata and notifies the listener provided at construction time if and only if the object has\n   * changed since the last call to {@link #getObject()} or {@code refresh()}.\n   */\n  @VisibleForTesting\n  void refresh(final Consumer<InputStream> changeListener) {\n    try {\n      final HeadObjectResponse objectMetadata = s3Client.headObject(HeadObjectRequest.builder()\n          .bucket(s3Bucket)\n          .key(objectKey)\n          .build());\n\n      final String initialETag = lastETag.get();\n      final String refreshedETag = objectMetadata.eTag();\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/s3/S3ObjectMonitor.java#L136-L172","documentation":"S3ObjectMonitor.getObject enforces a maximum object size when reading the monitored S3 object. If the S3 object's content length exceeds maxObjectSize, the response is aborted and an IOException('S3 object too large') is thrown to prevent loading an unexpectedly huge object into memory. This is a safety guard for configuration data fetched from S3.","triggerScenarios":"Calling getObject()/refresh()/refreshAfterGet() when the monitored S3 object (bucket/key from config) has been replaced with content larger than the configured maxObjectSize bytes.","commonSituations":"Someone uploaded an oversized or wrong file to the config bucket/key, an environment pointed the monitor at the wrong S3 key, or a tool wrote concatenated/bloated data to the object.","solutions":["Inspect the logged sizes: compare the object's actual size to the configured maxObjectSize.","Re-upload a correctly sized object to s3://<bucket>/<key>.","Verify the S3 bucket/key configuration points at the intended object.","If the object legitimately grew, raise the maxObjectSize configuration value deliberately."],"exampleFix":"// before: oversized object uploaded, monitor crashes\naws s3 cp huge-config.json s3://config-bucket/keys.json\n\n// after: enforce a sane size before upload, or raise the limit intentionally\naws s3 cp config.json s3://config-bucket/keys.json\n# or in server config:\n# maxObjectSize: 10485760  # raised deliberately","handlingStrategy":"validation","validationCode":"// before pointing the monitor at an object, check its size\nHeadObjectResponse head = s3.headObject(HeadObjectRequest.builder().bucket(bucket).key(objectKey).build());\nif (head.contentLength() > maxObjectSize) {\n  throw new IllegalStateException(\"Config object too large: \" + head.contentLength());\n}","typeGuard":null,"tryCatchPattern":"try {\n  monitor.refresh();\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"S3 object too large\")) {\n    alert.ops(\"Monitored S3 object oversized — check \" + bucket + \"/\" + key);\n  }\n}","preventionTips":["Gate uploads to the config bucket with a size check (CI or upload script).","Verify bucket/key config values when deploying to a new environment.","Keep maxObjectSize documented next to the object producer so limits stay aligned."],"tags":["s3","aws","file-size","config"],"backgroundTag":"file-size-limit-exceeded","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"}