diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index a3a6c37a947..f8261ea6398 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -108,6 +108,8 @@ New Features
* SOLR-8998: introducing uniqueBlock(_root_) aggregation as faster alternative to unique(_root_) for counting
child value facets in parents via json.facet on block index (Dr Oleg Savrasov, Mikhail Khludnev)
+* SOLR-11278: Add IgnoreLargeDocumentProcessFactory (Cao Manh Dat, David Smiley)
+
Bug Fixes
----------------------
diff --git a/solr/core/src/java/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactory.java b/solr/core/src/java/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactory.java
new file mode 100644
index 00000000000..17824384c8a
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/update/processor/IgnoreLargeDocumentProcessorFactory.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.update.processor;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.AddUpdateCommand;
+
+import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
+import static org.apache.solr.common.SolrException.ErrorCode.SERVER_ERROR;
+
+/**
+ *
+ * Gives system administrators a way to ignore very large update from clients.
+ * When an update goes through processors its size can change
+ * therefore this processor should be the last processor of the chain.
+ *
+ * @since 7.4.0
+ */
+public class IgnoreLargeDocumentProcessorFactory extends UpdateRequestProcessorFactory {
+ public static final String LIMIT_SIZE_PARAM = "limit";
+
+ // limit of a SolrInputDocument size (in kb)
+ private long maxDocumentSize = 1024 * 1024;
+
+ @Override
+ public void init(NamedList args) {
+ maxDocumentSize = args.toSolrParams().required().getLong(LIMIT_SIZE_PARAM);
+ args.remove(LIMIT_SIZE_PARAM);
+
+ if (args.size() > 0) {
+ throw new SolrException(SERVER_ERROR,
+ "Unexpected init param(s): '" +
+ args.getName(0) + "'");
+ }
+ }
+
+ @Override
+ public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) {
+ return new UpdateRequestProcessor(next) {
+ @Override
+ public void processAdd(AddUpdateCommand cmd) throws IOException {
+ long docSize = ObjectSizeEstimator.fastEstimate(cmd.getSolrInputDocument());
+ if (docSize / 1024 > maxDocumentSize) {
+ throw new SolrException(BAD_REQUEST, "Size of the document "+cmd.getPrintableId()+" is too large, around:"+docSize);
+ }
+ super.processAdd(cmd);
+ }
+ };
+ }
+
+ /**
+ * Util class for quickly estimate size of a {@link org.apache.solr.common.SolrInputDocument}
+ * Compare to {@link org.apache.lucene.util.RamUsageEstimator}, this class have some pros
+ *
+ *
does not use reflection
+ *
go as deep as needed to compute size of all {@link org.apache.solr.common.SolrInputField} and
+ * all {@link org.apache.solr.common.SolrInputDocument} children
+ *
compute size of String based on its length
+ *
fast estimate size of a {@link java.util.Map} or a {@link java.util.Collection}
+ *