infiniflow/ragflow · critical · ValueError
No private key
Error message
No private key
What it means
ValueError raised by decrypt_database_password in common/config_utils.py:113-133. When the service config enables password encryption (encrypt_password: true in service_conf.yaml), database passwords stored in the config are expected to be ciphertext decrypted with a private key configured at base.private_key. If encrypt_password is on but private_key is missing/null, decryption cannot proceed and the loader refuses to continue with a vague 'No private key' error.
Source
Thrown at common/config_utils.py:128
def get_base_config(key, default=None):
if key is None:
return None
if default is None:
default = os.environ.get(key.upper())
return CONFIGS.get(key, default)
def decrypt_database_password(password):
encrypt_password = get_base_config("encrypt_password", False)
encrypt_module = get_base_config("encrypt_module", False)
private_key = get_base_config("private_key", None)
if not password or not encrypt_password:
return password
if not private_key:
raise ValueError("No private key")
module_fun = encrypt_module.split("#")
pwdecrypt_fun = getattr(importlib.import_module(module_fun[0]), module_fun[1])
return pwdecrypt_fun(private_key, password)
def decrypt_database_config(database=None, passwd_key="password", name="database"):
if not database:
database = get_base_config(name, {})
database[passwd_key] = decrypt_database_password(database[passwd_key])
return database
def update_config(key, value, conf_name=SERVICE_CONF):
conf_path = conf_realpath(conf_name=conf_name)
if not os.path.isabs(conf_path):View on GitHub (pinned to 554fb1133a)
Solutions
- Add base.private_key to service_conf.yaml pointing at (or containing) the RSA private key used to encrypt the password.
- If you do not actually use encrypted passwords, set encrypt_password: false and store the plaintext DB password (or use environment variables) instead.
- Ensure encrypt_module is also set correctly (module#function) — it is required in the very next line once the key check passes.
Example fix
# before (service_conf.yaml) encrypt_password: true # no private_key # after encrypt_password: true private_key: "-----BEGIN RSA PRIVATE KEY-----..." # or, if not using encryption: # encrypt_password: false
Defensive patterns
Strategy: validation
Validate before calling
from common.config_utils import get_base_config
if get_base_config("encrypt_password", False) and not get_base_config("private_key", None):
raise RuntimeError("encrypt_password is enabled but private_key is missing — refusing to start") Try / catch
try:
decrypt_database_config()
except ValueError as e:
if str(e) == "No private key":
# fail fast with an operator-actionable message about base.private_key
raise RuntimeError("Set base.private_key or disable encrypt_password in service_conf.yaml") from e
raise Prevention
- If you enable encrypt_password, store private_key in the same change/commit.
- Keep encryption settings and key together in local.service_conf.yaml (git-ignored).
- Add a startup assertion pairing encrypt_password with private_key.
When it happens
Trigger: service_conf.yaml (or local.service_conf.yaml) sets encrypt_password: true and supplies an encrypted mysql/password value, but private_key is absent or null. Fires during decrypt_database_config at startup when the DB connection settings are prepared.
Common situations: Copying a production-style config that enables encryption without copying the key; rotating keys and forgetting to update private_key; enabling encrypt_password as an experiment and leaving it on; the key living in a different config stanza than expected.
Related errors
- Can't init admin.
- Invalid config file: "{local_path}".
- Invalid config file: "{global_config_path}".
- No active admin. Please update 'is_active' in db manually.
- Invalid Tenki provider configuration.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/40f3fd185e7f6372.
Report an issue: GitHub.