kubernetes/kubernetes · critical

retry backoff parameters for authorization webhook has not b

Error message

retry backoff parameters for authorization webhook has not been specified

What it means

Thrown during authorization webhook reload (buildAuthorizers) when r.initialConfig.WebhookRetryBackoff is nil but a Webhook authorizer type is configured. The webhook authorizer needs backoff parameters for retries; their absence prevents constructing the webhook authorizer on (re)load.

Source

Thrown at pkg/kubeapiserver/authorizer/reload.go:154

		case authzconfig.AuthorizerType(modes.ModeAlwaysDeny):
			alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer()
			authorizers = append(authorizers, union.NamedAuthorizer{
				AuthorizerName: configuredAuthorizer.Name,
				Authorizer:     authorizationmetrics.InstrumentedAuthorizer(string(configuredAuthorizer.Type), configuredAuthorizer.Name, alwaysDenyAuthorizer),
			})
			ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer)
		case authzconfig.AuthorizerType(modes.ModeABAC):
			if r.abacAuthorizer == nil {
				return nil, nil, fmt.Errorf("authorizer type ABAC is not allowed if it was not enabled at initial server startup")
			}
			authorizers = append(authorizers, union.NamedAuthorizer{
				AuthorizerName: configuredAuthorizer.Name,
				Authorizer:     authorizationmetrics.InstrumentedAuthorizer(string(configuredAuthorizer.Type), configuredAuthorizer.Name, r.abacAuthorizer),
			})
			ruleResolvers = append(ruleResolvers, r.abacAuthorizer)
		case authzconfig.AuthorizerType(modes.ModeWebhook):
			if r.initialConfig.WebhookRetryBackoff == nil {
				return nil, nil, errors.New("retry backoff parameters for authorization webhook has not been specified")
			}
			clientConfig, err := webhookutil.LoadKubeconfig(*configuredAuthorizer.Webhook.ConnectionInfo.KubeConfigFile, r.initialConfig.CustomDial)
			if err != nil {
				return nil, nil, err
			}
			if configuredAuthorizer.Webhook.Timeout.Duration != 0 {
				clientConfig.Timeout = configuredAuthorizer.Webhook.Timeout.Duration
			}
			var decisionOnError authorizer.Decision
			switch configuredAuthorizer.Webhook.FailurePolicy {
			case authzconfig.FailurePolicyNoOpinion:
				decisionOnError = authorizer.DecisionNoOpinion
			case authzconfig.FailurePolicyDeny:
				decisionOnError = authorizer.DecisionDeny
			default:
				return nil, nil, fmt.Errorf("unknown failurePolicy %q", configuredAuthorizer.Webhook.FailurePolicy)
			}

View on GitHub (pinned to b882c60b40)

Solutions

  1. Provide a non-nil WebhookRetryBackoff in the authorizer reload initialConfig (mirroring the apiserver default backoff).
  2. Ensure the kube-apiserver sets the default backoff whenever webhook authorization is enabled.
  3. If running a custom authorization reload path, populate initialConfig.WebhookRetryBackoff before buildAuthorizers.

Example fix

// before
// initialConfig.WebhookRetryBackoff = nil
// after
// initialConfig.WebhookRetryBackoff = &wait.Backoff{Duration: 500*time.Millisecond, Factor: 1.5, Jitter: 0.2, Steps: 5}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure backoff is set before authorizer reload builds webhook authorizers
if initialConfig.WebhookRetryBackoff == nil { initialConfig.WebhookRetryBackoff = defaultWebhookBackoff() }

Prevention

When it happens

Trigger: An authorization configuration (AuthorizationConfig) with an authorizer of type Webhook while initialConfig.WebhookRetryBackoff was never set. The reload logic cannot build the webhook authorizer.

Common situations: Using --authorization-webhook-config-file or a structured AuthorizationConfig with webhook authorizers but the reloader's initialConfig lacks the backoff; embedded apiserver wiring that skipped the backoff default; reload after a config change exposing the missing field.

Related errors


AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07). Data as JSON: /api/errors/460ad496b6df208c. Report an issue: GitHub.