zylon-ai/private-gpt · critical · ValueError
Visibility timeout should be set when broker or backend is R
Error message
Visibility timeout should be set when broker or backend is Redis
What it means
Config-validation ValueError from CelerySettings.validate_config: when broker_mode or backend_mode is 'redis', visibility_timeout must be set. With Redis, Celery's early-ack behavior can redeliver a task before it finishes, producing duplicates unless visibility_timeout exceeds the longest task; the validator therefore refuses Redis configs without it.
Source
Thrown at private_gpt/settings/settings.py:1163
int(data["hard_time_limit"]) if data["hard_time_limit"] else None
)
if "max_memory_per_child" in data:
data["max_memory_per_child"] = (
int(data["max_memory_per_child"])
if data["max_memory_per_child"]
else None
)
if "visibility_timeout" in data:
data["visibility_timeout"] = (
int(data["visibility_timeout"]) if data["visibility_timeout"] else None
)
super().__init__(**data)
def validate_config(self) -> bool:
# Check if visibility timeout is set when broker or backend is redis
if self.broker_mode == "redis" or self.backend_mode == "redis":
if not self.visibility_timeout:
raise ValueError(
"Visibility timeout should be set when broker or backend is Redis"
)
if self.soft_time_limit:
if self.hard_time_limit and self.soft_time_limit > self.hard_time_limit:
raise ValueError(
"Soft time limit should be less than or equal to hard time limit"
)
if (
self.visibility_timeout
and self.visibility_timeout < self.soft_time_limit
):
raise ValueError(
"Visibility timeout should be greater than soft time limit"
)
if self.hard_time_limit:View on GitHub (pinned to 4a030776a3)
Solutions
- Set celery visibility_timeout in settings (seconds), e.g. visibility_timeout: 3600 — comfortably above your longest task.
- If it is set but ignored, check the env/YAML value is not empty/0 (the loader maps falsy to None) and the key nesting matches the schema.
- If you did not intend Redis, set broker_mode/backend_mode back to the intended non-redis value.
- Restart the API and worker processes after fixing the config — validation runs at settings load.
Example fix
# before (settings.yaml) celery: broker_mode: redis backend_mode: redis # after celery: broker_mode: redis backend_mode: redis visibility_timeout: 7200
Defensive patterns
Strategy: validation
Validate before calling
cfg = load_settings_profile('prod')
celery_cfg = cfg.get('celery', {})
if 'redis' in (celery_cfg.get('broker_mode'), celery_cfg.get('backend_mode')):
assert int(celery_cfg.get('visibility_timeout') or 0) > 0, 'redis celery needs visibility_timeout' Type guard
const redisNeedsVisibility = (c: { broker_mode?: string; backend_mode?: string; visibility_timeout?: number }): boolean =>
(c.broker_mode === 'redis' || c.backend_mode === 'redis') && !c.visibility_timeout; Prevention
- Add a pre-deploy config lint that enforces the visibility_timeout/redis invariant.
- Keep a canonical Redis Celery block in config templates.
- Re-validate with `python -c 'from private_gpt.settings.settings import Settings'` in CI.
When it happens
Trigger: settings.yaml (or env vars) with celery broker_mode: redis and/or backend_mode: redis but no visibility_timeout (or an explicit null/0 — the loader coerces falsy values to None). Switching the broker from rabbitmq to redis in an existing config that never had the key.
Common situations: Migrating from RabbitMQ to Redis for simpler ops and reusing the old YAML; adding a redis backend for result tracking; visibility_timeout set to 0 or empty string in env vars being coerced to None; copy-pasted minimal example configs.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Soft time limit should be less than or equal to hard time li
- Visibility timeout should be greater than soft time limit
- Visibility timeout should be greater than hard time limit
- Unsupported scheduler.tools.mode={self.scheduler.tools.mode!
- scheduler.tools.mode={self.scheduler.tools.mode!r} requires
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/a5dc9746653738cd.
Report an issue: GitHub.