private long parallelReplicate(ReplicateContext replicateContext, List<List<Entry>> batches)
    throws IOException {
    List<CompletableFuture<Integer>> futures =
      new ArrayList<CompletableFuture<Integer>>(batches.size());
    for (int i = 0; i < batches.size(); i++) {
      List<Entry> entries = batches.get(i);
      if (entries.isEmpty()) {
        continue;
      }
      if (LOG.isTraceEnabled()) {
        LOG.trace("{} Submitting {} entries of total size {}", logPeerId(), entries.size(),
          replicateContext.getSize());
      }
      // RuntimeExceptions encountered here bubble up and are handled in ReplicationSource
      futures.add(asyncReplicate(entries, i, replicateContext.getTimeout()));
    }

    IOException iox = null;
    long lastWriteTime = 0;

    for (CompletableFuture<Integer> f : futures) {
      try {
        // wait for all futures, remove successful parts
        // (only the remaining parts will be retried)
        int index = FutureUtils.get(f);
        List<Entry> batch = batches.get(index);
        batches.set(index, Collections.emptyList()); // remove successful batch
        // Find the most recent write time in the batch
        long writeTime = batch.get(batch.size() - 1).getKey().getWriteTime();
        if (writeTime > lastWriteTime) {
          lastWriteTime = writeTime;
        }
      } catch (IOException e) {
        iox = e;
      } catch (RuntimeException e) {
        iox = new IOException(e);
      }
    }
    if (iox != null) {
      // if we had any exceptions, try again
      throw iox;
    }
    return lastWriteTime;
  }
Check if there's an {@link NoSuchColumnFamilyException} in the caused by stacktrace.
hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/HBaseInterClusterReplicationEndpoint.java