infiniflow/ragflow · error · RuntimeError

Exceed the maximum file number of a free user!

Error message

Exceed the maximum file number of a free user!

What it means

RuntimeError from DocumentService.check_doc_health when the environment variable MAX_FILE_NUM_PER_USER is set to a positive number and the tenant's existing document count has reached it. It is the free-tier file-count quota enforcement at upload time.

Source

Thrown at api/db/services/document_service.py:125

        count = docs.count()
        docs = docs.paginate(page_number, items_per_page)

        docs_list = list(docs.dicts())
        doc_ids_on_page = [doc["id"] for doc in docs_list]
        metadata_map = DocMetadataService.get_metadata_for_documents(doc_ids_on_page, kb_id) if doc_ids_on_page else {}
        for doc in docs_list:
            doc["meta_fields"] = metadata_map.get(doc["id"], {})
        return docs_list, count

    @classmethod
    @DB.connection_context()
    def check_doc_health(cls, tenant_id: str, filename):
        import os

        MAX_FILE_NUM_PER_USER = int(os.environ.get("MAX_FILE_NUM_PER_USER", 0))
        if 0 < MAX_FILE_NUM_PER_USER <= DocumentService.get_doc_count(tenant_id):
            raise RuntimeError("Exceed the maximum file number of a free user!")
        if len(filename.encode("utf-8")) > FILE_NAME_LEN_LIMIT:
            raise RuntimeError("Exceed the maximum length of file name!")
        return True

    @classmethod
    @DB.connection_context()
    def get_by_kb_id(cls, kb_id, page_number, items_per_page, orderby, desc, keywords, run_status, types, suffix, name=None, doc_ids=None, return_empty_metadata=False):
        fields = cls.get_cls_model_fields()
        if keywords:
            docs = (
                cls.model.select(*[*fields, UserCanvas.title.alias("pipeline_name"), User.nickname])
                .join(File2Document, on=(File2Document.document_id == cls.model.id))
                .join(File, on=(File.id == File2Document.file_id))
                .join(UserCanvas, on=(cls.model.pipeline_id == UserCanvas.id), join_type=JOIN.LEFT_OUTER)
                .join(User, on=(cls.model.created_by == User.id), join_type=JOIN.LEFT_OUTER)
                .where((cls.model.kb_id == kb_id), (fn.LOWER(cls.model.name).contains(keywords.lower())))
            )
        else:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Delete unneeded documents (and ensure they are purged from the count) or upgrade the user's quota.
  2. If you operate the deployment, raise or unset MAX_FILE_NUM_PER_USER.
  3. Check the count first via get_doc_count before uploading to give users an early warning.

Example fix

# before: MAX_FILE_NUM_PER_USER=100 and user has 100 docs, upload proceeds and fails
# after (operator)
# docker/...: - MAX_FILE_NUM_PER_USER=0  (disable) or a higher cap
Defensive patterns

Strategy: validation

Validate before calling

import os
from api.db.services.document_service import DocumentService

max_n = int(os.environ.get('MAX_FILE_NUM_PER_USER', 0) or 0)
if 0 < max_n <= DocumentService.get_doc_count(tenant_id):
    raise PermissionError(f'file quota ({max_n}) reached — delete documents first')

Try / catch

try:
    DocumentService.check_doc_health(tenant_id, filename)
except RuntimeError as e:
    if 'maximum file number' in str(e):
        notify_user_quota_reached()  # block upload in UI instead of failing
    else:
        raise

Prevention

When it happens

Trigger: Uploading a document while MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(tenant_id) >= that limit (env default 0 disables the check).

Common situations: SaaS/multi-tenant deployments capping free users; raising the env var expectation after deleting documents that are still counted (soft-deleted rows); shared dev environment hitting the cap during bulk tests.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/0c3c1d5ce4535e1e. Report an issue: GitHub.