cockroachdb/cockroach · error · Error
Unable to retrieve the Jobs table.
Error message
Unable to retrieve the Jobs table.
What it means
getJobs in db-console wraps timeoutFetch of `_admin/jobs?status=&type=&limit=`; when the fetch exceeds its deadline, the TimeoutError is converted to this fixed message (jobsTimeoutErrorMessage = 'Unable to retrieve the Jobs table.') while the URL and request are console.error'd. Non-timeout errors propagate unchanged, so seeing this exact string means the admin jobs RPC was too slow, not failed.
Source
Thrown at pkg/ui/workspaces/db-console/src/util/api.ts:415
export const jobsTimeoutErrorMessage = "Unable to retrieve the Jobs table.";
export function getJobs(
req: JobsRequestMessage,
timeout?: moment.Duration,
): Promise<JobsResponseMessage> {
const url = `${API_PREFIX}/jobs?status=${req.status}&type=${req.type}&limit=${req.limit}`;
return timeoutFetch(serverpb.JobsResponse, url, null, timeout).then(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
(response: JobsResponseMessage) => response,
(err: Error) => {
if (err instanceof TimeoutError) {
// eslint-disable-next-line no-console
console.error(
`Jobs page time out because attempt to retrieve jobs exceeded ${err.timeout.asMilliseconds()}ms.`,
`URL: ${url}. Request: ${JSON.stringify(req)}`,
);
throw new Error(jobsTimeoutErrorMessage);
} else {
throw err;
}
},
);
}
export function getJob(
req: JobRequestMessage,
timeout?: moment.Duration,
): Promise<JobResponseMessage> {
return timeoutFetch(
serverpb.JobResponse,
`${API_PREFIX}/jobs/${req.job_id}`,
null,
timeout,
);
}View on GitHub (pinned to 8812064a01)
Solutions
- Retry the page once after a few seconds — registry contention is often transient
- Narrow the request: filter by status and type and lower limit before loading
- If persistent, capture a goroutine dump (/_status/stacks or debug zip) to find what holds the jobs registry mutex
- As a last resort raise the timeout passed to getJobs for this page on known-slow clusters
Example fix
// before
const [jobs, setJobs] = useState(null);
getJobs(req).then(setJobs);
// after: one bounded retry for the timeout-specific message
import { jobsTimeoutErrorMessage } from 'src/util/api';
const load = (attempt: number) =>
getJobs(req).catch(err => {
if (err.message === jobsTimeoutErrorMessage && attempt < 1) {
return new Promise(r => setTimeout(r, 3000)).then(() => load(attempt + 1));
}
throw err;
}); Defensive patterns
Strategy: retry
Validate before calling
// Keep requests bounded before loading
const bounded = {
...req,
limit: Math.min(req.limit, 100),
status: req.status || 'running',
type: req.type || '',
}; Type guard
const isJobsTimeoutError = (e: unknown): e is Error => e instanceof Error && e.message === 'Unable to retrieve the Jobs table.';
Try / catch
import { jobsTimeoutErrorMessage } from 'src/util/api';
const loadJobs = async (attempt = 0): Promise<JobsResponseMessage> => {
try {
return await getJobs(req);
} catch (e) {
if (e.message === jobsTimeoutErrorMessage && attempt < 2) {
await new Promise(r => setTimeout(r, 3000 * (attempt + 1)));
return loadJobs(attempt + 1);
}
throw e;
}
}; Prevention
- Always filter by status/type and use a small limit on large clusters
- Retry with backoff on this specific message — it signals slowness, not permanent failure
- If timeouts persist, capture goroutine dumps to identify registry-mutex contention
When it happens
Trigger: GET /_admin/jobs not answering within the timeout: the jobs registry mutex held by a long operation on a node, very high limit combined with thousands of jobs, slow RPC fan-out across many nodes, or an overloaded node.
Common situations: Large clusters with heavy backup/restore/changefeed job churn; opening the Jobs page unfiltered with a big limit during node stress; transient GC pauses or disk stalls on a node making job enumeration slow.
Related errors
- Error response from server: ${resp.status}
- Error while retrieving statements information: ${sqlApiError
- Error while retrieving statements information: ${sqlApiError
- Table ID is required
- Failed to collect execution details
AI-assisted analysis of cockroachdb/cockroach@8812064a01 (2026-08-15).
Data as JSON: /api/errors/fbf3440cfb58fac6.
Report an issue: GitHub.