zylon-ai/private-gpt · critical · ValueError
Soft time limit should be less than or equal to hard time li
Error message
Soft time limit should be less than or equal to hard time limit
What it means
Config-validation ValueError from CelerySettings.validate_config: soft_time_limit must be <= hard_time_limit when both are set. Celery raises SoftTimeLimitExceeded inside the task at the soft limit so it can clean up, while the hard limit kills the worker process; an inversion of that ordering would make the soft signal useless, so the settings validator rejects it at startup.
Source
Thrown at private_gpt/settings/settings.py:1169
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:
if (
self.visibility_timeout
and self.visibility_timeout < self.hard_time_limit
):
raise ValueError(
"Visibility timeout should be greater than hard time limit"View on GitHub (pinned to 4a030776a3)
Solutions
- Make soft_time_limit <= hard_time_limit (typical pattern: soft = 80-90% of hard), e.g. soft 240 / hard 300.
- If the hard limit was lowered intentionally, lower the soft limit to match.
- Audit both environments' overrides (YAML + env vars) — the effective pair must satisfy the invariant everywhere.
- After editing, restart services so settings re-validate.
Example fix
# before celery: soft_time_limit: 600 hard_time_limit: 300 # after celery: soft_time_limit: 240 hard_time_limit: 300
Defensive patterns
Strategy: validation
Validate before calling
soft, hard = cfg['celery'].get('soft_time_limit'), cfg['celery'].get('hard_time_limit')
if soft and hard:
assert soft <= hard, f'soft ({soft}) must be <= hard ({hard})' Type guard
const limitsOrdered = (c: { soft_time_limit?: number; hard_time_limit?: number }): boolean =>
c.soft_time_limit == null || c.hard_time_limit == null || c.soft_time_limit <= c.hard_time_limit; Prevention
- Derive soft_time_limit from hard_time_limit (e.g. 0.8x) in templates so they cannot invert.
- Review both limits together in change requests.
- Run the settings loader in CI for every environment overlay.
When it happens
Trigger: settings.yaml or env with soft_time_limit: 300 and hard_time_limit: 120; setting only one limit per environment (dev vs prod) and them drifting; unit confusion (seconds vs milliseconds) making soft appear larger.
Common situations: Ops tightening the hard limit in production without adjusting the soft limit; configs templated from examples with mismatched values; env var overrides applied to one limit only.
Related errors
- Visibility timeout should be set when broker or backend is R
- 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/4fa9377591ded3bc.
Report an issue: GitHub.