{"record":{"id":"3297fec83bc0e3a5","repo":"redis/jedis","slug":"malformed-moving-push","errorCode":null,"errorMessage":"Malformed MOVING push: ","messagePattern":"Malformed MOVING push: ","errorType":"exception","errorClass":"MalformedMaintenanceEventException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/MaintenancePushCodec.java","lineNumber":70,"sourceCode":"          return null;\n      }\n    }\n  }\n\n  /**\n   * Builds the domain event for an already-resolved push type.\n   * @throws MalformedMaintenanceEventException if the frame's fields are malformed (missing or\n   *           wrong-typed seq/time/shards, or a MOVING with a missing or unparseable target — a\n   *           null target is valid and denotes the {@code none} endpoint type)\n   */\n  static MaintenanceEvent build(PushType type, PushMessage msg) {\n    return type.decoder.apply(msg.getContent());\n  }\n\n  private static MaintenanceEvent moving(List<Object> c) { // [MOVING, seq, time_s, host:port |\n                                                           // null]\n    if (c.size() < 4 || !(c.get(1) instanceof Long) || !(c.get(2) instanceof Long)) {\n      throw malformed(\"MOVING\", c);\n    }\n    // Explicit RESP3 null target => 'none' endpoint type (no remap). A byte[] target is parsed;\n    // anything else (wrong type, unparseable) is malformed.\n    HostAndPort target = c.get(3) == null ? null : parseHostPort(c, 3);\n    return new MovingEvent((Long) c.get(1), (Long) c.get(2), target);\n  }\n\n  private static MaintenanceEvent migrating(List<Object> c) { // [MIGRATING, seq, time_s, shards]\n    if (c.size() < 4 || !(c.get(1) instanceof Long) || !(c.get(2) instanceof Long)\n        || !(c.get(3) instanceof byte[])) {\n      throw malformed(\"MIGRATING\", c);\n    }\n    return new MigratingEvent((Long) c.get(1), (Long) c.get(2), shardIds(c, 3));\n  }\n\n  private static MaintenanceEvent failingOver(List<Object> c) { // [FAILING_OVER, seq, time_s,\n                                                                // shards]\n    if (c.size() < 4 || !(c.get(1) instanceof Long) || !(c.get(2) instanceof Long)","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/MaintenancePushCodec.java#L52-L88","documentation":"MaintenancePushCodec.moving() parses RESP3 push notifications of type MOVING (sent during Redis Enterprise maintenance operations). If the payload list is too short or the seq/time fields are not Longs, a malformed exception is thrown describing the raw content. A null target is valid (means 'none' endpoint); a wrong-type or unparseable host:port target is also treated as malformed by parseHostPort.","triggerScenarios":"A MOVING push arrives with fewer than 4 elements, non-Long seq/time_s, or an unparseable/non-byte[] host:port — e.g. protocol incompatibility between the server's push format and the client codec, or corrupted/interleaved push data.","commonSituations":"Connecting a mismatched jedis version to a Redis Enterprise cluster using a newer/older maintenance push schema; custom proxies rewriting push payloads; RESP2 clients receiving push frames unexpectedly.","solutions":["Upgrade jedis to the version matching your Redis Enterprise server's push schema.","Log and report the raw content included in the error to correlate with server version.","Verify the connection is RESP3-capable (protocol=3) where maintenance pushes require it.","Check for intermediary proxies mutating push payloads and bypass them if possible."],"exampleFix":"// before\nJedisClientConfig cfg = ...; // protocol RESP2\n// after\ndefaultRedisClientBuilder.protocol(RedisProtocol.RESP3) // enable RESP3 pushes","handlingStrategy":"validation","validationCode":"// require RESP3 and matching client version before maintenance-aware features\nif (config.getProtocol() != RedisProtocol.RESP3) {\n  throw new IllegalArgumentException(\"Maintenance pushes require RESP3\");\n}","typeGuard":"// validate expected MOVING shape: [MOVING, Long, Long, target]\nstatic boolean isValidMoving(List<Object> c) {\n  return c.size() >= 4 && c.get(1) instanceof Long && c.get(2) instanceof Long\n      && (c.get(3) == null || c.get(3) instanceof byte[]);\n}","tryCatchPattern":"try {\n  handle(codec.decode(push));\n} catch (JedisException e) { // malformed push\n  log.warn(\"Unparseable maintenance push, ignoring: {}\", e.getMessage());\n}","preventionTips":["Run a jedis version matching your Redis Enterprise server version","Use RESP3 protocol where maintenance pushes are expected","Avoid custom proxies in the push path","Pin client/server versions and test maintenance events in staging"],"tags":["redis","resp3","push","maintenance","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}