kubernetes/kubernetes · error
variable composition is not allowed
Error message
variable composition is not allowed
What it means
Returned as a field.InternalError when validating a ValidatingAdmissionPolicy variable definition and the CEL compiler passed to the validator is not a *plugincel.CompositedCompiler (i.e. it does not support variable composition / expression compilation and storage). This is an internal/server-side configuration problem, not a user-facing CEL expression error.
Source
Thrown at pkg/apis/admissionregistration/validation/validation.go:1028
} else {
if compiler, ok := compiler.(*plugincel.CompositedCompiler); ok {
envType := environment.NewExpressions
if opts.preexistingExpressions.validationExpressions.Has(v.Expression) {
envType = environment.StoredExpressions
}
variable := &validatingadmissionpolicy.Variable{
Name: v.Name,
Expression: v.Expression,
}
result := compiler.CompileAndStoreVariable(variable, plugincel.OptionalVariableDeclarations{
HasParams: paramKind != nil,
HasAuthorizer: true,
}, envType)
if result.Error != nil {
allErrors = append(allErrors, convertCELErrorToValidationError(fldPath.Child("expression"), variable, result.Error))
}
} else {
allErrors = append(allErrors, field.InternalError(fldPath, fmt.Errorf("variable composition is not allowed")))
}
}
return allErrors
}
func validateValidation(compiler plugincel.Compiler, v *admissionregistration.Validation, paramKind *admissionregistration.ParamKind, opts validationOptions, fldPath *field.Path) field.ErrorList {
var allErrors field.ErrorList
trimmedExpression := strings.TrimSpace(v.Expression)
trimmedMsg := strings.TrimSpace(v.Message)
trimmedMessageExpression := strings.TrimSpace(v.MessageExpression)
if len(trimmedExpression) == 0 {
allErrors = append(allErrors, field.Required(fldPath.Child("expression"), "expression is not specified"))
} else {
allErrors = append(allErrors, validateValidationExpression(compiler, v.Expression, paramKind != nil, opts, fldPath.Child("expression"))...)
}
if len(v.MessageExpression) > 0 && len(trimmedMessageExpression) == 0 {
allErrors = append(allErrors, field.Invalid(fldPath.Child("messageExpression"), v.MessageExpression, "must be non-empty if specified"))
} else if len(trimmedMessageExpression) != 0 {View on GitHub (pinned to 94c1367642)
Solutions
- Upgrade the API server to a version that registers the CompositedCompiler for admission policy validation.
- If running a custom apiserver, ensure the CEL environment factory returns a *plugincel.CompositedCompiler (see plugincel.NewCompositedCompiler).
- If you cannot upgrade, remove spec.variables from the ValidatingAdmissionPolicy and inline the expressions.
Example fix
// before — custom apiserver wires a plain compiler compiler := cel.NewCompiler(env) // after — use the composited compiler that supports variable composition compiler := plugincel.NewCompositedCompiler(env, optionalDeclarations)
Defensive patterns
Strategy: validation
Prevention
- Ensure the API server registers plugincel.NewCompositedCompiler for admission validation.
- Do not deploy ValidatingAdmissionPolicies with spec.variables on API servers that predate variable support.
- Run a conformance/compatibility check: submit a trivial policy with one variable against the target server.
When it happens
Trigger: A ValidatingAdmissionPolicy that declares one or more variables (spec.variables) is submitted to an API server whose admission CEL compiler is a plain compiler that lacks the CompositedCompiler type. The validator checks the compiler type at runtime and fails because variable composition requires storing compiled expressions.
Common situations: Running a custom API server build that wires a minimal CEL compiler without the composition plugin; version skew where the API server binary predates variable support but the CRD/policy schema accepts variables; test harness using a mock compiler.
Related errors
- unsupported error type: %w
- unexpected GroupVersion string: %v
- no request info in context
- no authorizer available
- ValidatingAdmissionPolicy %q: %w
AI-assisted analysis of kubernetes/kubernetes@94c1367642 (2026-08-08).
Data as JSON: /api/errors/c91aa86541fd0475.
Report an issue: GitHub.