Skip to content

A failed estate Job stays failed until what names it changes #461

Open

Description

@ExtraToast

What happened

The Vault policy job and the catalog method's Job are named by a digest of what they run with (#454, #459). On 2026-10-16 the first postgres-catalog-7b66ab65da64 failed, because the Vault policy job had not yet written its role. Once a fixed policy job had run, the catalog Job's inputs were unchanged, so it kept its name and stayed Failed. Flux's health check kept estate-vso-secrets not Ready, which held apps-delivery, apps-tribelt and apps-estate-dashboard, until the Job was deleted by hand. The hourly CronJob runs the same pod and succeeded, but the unit's health check reads the hash-named Job.

What should happen

A Job that failed for a reason outside its own inputs runs again without a person deleting it. Options: the unit does not health-check the one-shot Job and relies on the CronJob, the Job carries a backoffLimit and deadline long enough to outlast the policy job writing its role, or the catalog Job is ordered after the policy job.

Acceptance criteria

  • A catalog Job that fails because its Vault role does not exist yet succeeds on its own once the role exists, with no manual delete.
  • Both implementations and the oracle trees agree.

Activity

  1. added
    type: bugSomething is broken or behaving incorrectly.
    area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.
    status: ready-for-agentFully specified; an agent may take it with nobody watching.
    on Oct 16, 2026
  2. added and removed
    status: ready-for-agentFully specified; an agent may take it with nobody watching.
    on Oct 29, 2026
  3. ExtraToast commented on Oct 29, 2026

    @ExtraToast
    ContributorAuthor

    #473 (merged 2026-10-17, for #472) already fixes this, so I opened no PR. I recommend closing this issue as completed. I could not close it from here. #473 took the issue's second option:

    • restartPolicy: OnFailure, and the deadline moved onto the pod as activeDeadlineSeconds, so it limits one attempt instead of the whole Job.
    • The Job has backoffLimit: 2147483647 and no deadline of its own. A catalog Job whose Vault role does not exist yet keeps retrying, using the Job controller's backoff, which tops out at 6 minutes. The first attempt after the policy job writes the role succeeds. The Job never reaches Failed, so its hash name can no longer leave it stuck.
    • The hourly CronJob carries the same backoffLimit.

    Where it lives on main:

    • code: src/adapters/kubernetes/catalog.ts and src/adapters/vault-policy/job.ts, both using UNTIL_SUCCEEDED from src/adapters/shared/placement.ts;
    • oracle: spec/v1/examples/knowledge-platform/rendered/estate/vso-secrets/postgres-catalog.yaml pins backoffLimit, restartPolicy and the per-attempt deadline byte for byte;
    • spec: chapter 16 #applying-the-catalog and chapter 30's job.yaml row;
    • decision: 0103, whose "Settled by" is this same kind of recovery.

    emf/ matched when #473 merged and has been frozen at mde-task-3 since then, so the second criterion stands as of that merge.

    The live proof is still open: a catalog Job that fails, then succeeds, with no manual delete. That needs someone watching the cluster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.type: bugSomething is broken or behaving incorrectly.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions