argoproj/argo-workflows · error
offload node status is not supported
Error message
offload node status is not supported
What it means
ErrOffloadNotSupported is the sentinel error returned by every method of the explosiveOffloadNodeStatusRepo (Save, Get, List, Delete, ListOldOffloads). This repo is a no-op stand-in used when offloading node status to the database is disabled; calling it signals the caller expected offload storage that is not configured.
Source
Thrown at persist/sqldb/explosive_offload_node_status_repo.go:12
package sqldb
import (
"context"
"fmt"
wfv1 "github.com/argoproj/argo-workflows/v4/pkg/apis/workflow/v1alpha1"
)
var (
ExplosiveOffloadNodeStatusRepo OffloadNodeStatusRepo = &explosiveOffloadNodeStatusRepo{}
ErrOffloadNotSupported = fmt.Errorf("offload node status is not supported")
)
type explosiveOffloadNodeStatusRepo struct{}
func (n *explosiveOffloadNodeStatusRepo) IsEnabled() bool {
return false
}
func (n *explosiveOffloadNodeStatusRepo) Save(context.Context, string, string, wfv1.Nodes) (string, error) {
return "", ErrOffloadNotSupported
}
func (n *explosiveOffloadNodeStatusRepo) Get(context.Context, string, string) (wfv1.Nodes, error) {
return nil, ErrOffloadNotSupported
}
func (n *explosiveOffloadNodeStatusRepo) List(context.Context, string) (map[UUIDVersion]wfv1.Nodes, error) {
return nil, ErrOffloadNotSupportedView on GitHub (pinned to 35bff19146)
Solutions
- Configure persistence (offload node status) in the workflow-controller-configmap so the real sqldb-backed offload repo is used instead of the explosive no-op.
- Guard callers with OffloadNodeStatusRepo.IsEnabled() before calling Save/Get/Delete.
- If writing tests, use the explosive repo only for paths that tolerate ErrOffloadNotSupported or mock the repo interface.
- Verify which repo the controller wired at startup (logs) and correct the wiring/config.
Example fix
// before
// nodes, err := offloadRepo.Get(ctx, wfNamespace, wfName)
// after
// if !offloadRepo.IsEnabled() {
// return nil // or read status from the workflow object
// }
// nodes, err := offloadRepo.Get(ctx, wfNamespace, wfName) Defensive patterns
Strategy: type-guard
Validate before calling
// check offloading before use
if !persist.OffloadNodeStatusRepo.IsEnabled() {
return errors.New("node status offloading is disabled; configure persistence")
} Type guard
func offloadAvailable(repo persist.OffloadNodeStatusRepo) bool {
return repo != nil && repo.IsEnabled()
} Try / catch
if err == persist.ErrOffloadNotSupported {
logger.Info(ctx, "offload disabled; falling back to inline node status")
return nil // read status from the Workflow object instead
} Prevention
- Call IsEnabled() before any offload repo operation.
- Configure persistence in the controller configmap if offloading is required.
- In tests, mock the repo instead of relying on the explosive no-op.
- Check controller startup logs to confirm which offload repo was wired.
When it happens
Trigger: Any controller code path calls ExplosiveOffloadNodeStatusRepo.Save/Get/List/Delete/ListOldOffloads while node status offloading is not enabled (IsEnabled() == false), e.g. when the workflow archive database is not configured.
Common situations: Running without persistence configured (no postgres/mysql offload) while a code path or test assumes offload; manually injecting the explosive repo; misconfigured persistence block in the controller configmap.
Related errors
- %sTried to offload but encountered error: %s
- artifact driver %s not found
- if you have an item in your config map named 'config', you m
- operation %v is not supported
- getting archived workflows not supported
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/c614e3975760ffc1.
Report an issue: GitHub.