cilium/cilium · error
CEC JSON decoding paniced: %v
Error message
CEC JSON decoding paniced: %v
What it means
XDSResource.UnmarshalJSON in pkg/k8s/apis/cilium.io/v2/cec_types.go decodes CiliumEnvoyConfig xDS resources with protojson.Unmarshal into an anypb.Any. Since protojson can panic on malformed input, a deferred recover converts any panic into this 'CEC JSON decoding paniced: %v' error so the K8s decode path does not crash the process.
Source
Thrown at pkg/k8s/apis/cilium.io/v2/cec_types.go:178
// DeepEqual returns 'true' if 'a' and 'b' are equal.
func (a *XDSResource) DeepEqual(b *XDSResource) bool {
return proto.Equal(a.Any, b.Any)
}
// MarshalJSON ensures that the unstructured object produces proper
// JSON when passed to Go's standard JSON library.
func (u *XDSResource) MarshalJSON() ([]byte, error) {
return protojson.Marshal(u.Any)
}
// UnmarshalJSON ensures that the unstructured object properly decodes
// JSON when passed to Go's standard JSON library.
func (u *XDSResource) UnmarshalJSON(b []byte) (err error) {
// xDS resources are not validated in K8s, recover from possible panics
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("CEC JSON decoding paniced: %v", r)
}
}()
u.Any = &anypb.Any{}
err = protojson.Unmarshal(b, u.Any)
if err != nil {
var buf bytes.Buffer
json.Indent(&buf, b, "", "\t")
// slogloggercheck: it's safe to use the default logger here as it has been initialized by the program up to this point.
logging.DefaultSlogLogger.Warn("Ignoring invalid CiliumEnvoyConfig JSON",
logfields.Error, err,
logfields.Object, buf,
)
} else if option.Config.Debug {
// slogloggercheck: it's safe to use the default logger here as it has been initialized by the program up to this point.
logging.DefaultSlogLogger.Debug("CEC unmarshaled XDS Resource", logfields.Resource, prototext.Format(u.Any))
}
return nil
}View on GitHub (pinned to ac7b90affa)
Solutions
- Validate the xds resource payload is proper protobuf JSON with a correct '@type' fully-qualified Any type name (e.g. type.googleapis.com/envoy.config...)
- Compare against a known-good CEC example from the cilium repo for your version and fix field names/types
- Convert the Envoy config using protoc/gogo protojson marshaling instead of hand-writing JSON
- Check cilium version compatibility of the resource schema and update the CEC accordingly
Example fix
// before resources: - "@type": envoy.config.filter... # wrong/abbreviated type // after resources: - "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router ...
Defensive patterns
Strategy: validation
Validate before calling
// validate the Any payload before creating the CEC
var anyObj map[string]any
if err := json.Unmarshal(xdsBytes, &anyObj); err != nil { return err }
t, ok := anyObj["@type"]
if !ok || !strings.HasPrefix(t.(string), "type.googleapis.com/") {
return fmt.Errorf("xds resource missing valid @type")
} Type guard
func hasValidAnyType(b []byte) bool {
var m struct{ Type string `json:"@type"` }
return json.Unmarshal(b, &m) == nil && strings.HasPrefix(m.Type, "type.googleapis.com/")
} Try / catch
if err := json.Unmarshal(rawCEC, &cec); err != nil {
if strings.HasPrefix(err.Error(), "CEC JSON decoding paniced") {
// reject resource, log payload, fix @type/protobuf-JSON
}
} Prevention
- Always use fully-qualified @type URLs in xds Any payloads
- Marshal Envoy config with protojson from generated Go types instead of hand-writing
- Test CEC manifests against the target cilium version's protobuf schemas
- Keep CEC examples versioned with the Envoy/cilium release
When it happens
Trigger: A CiliumEnvoyConfig (CEC) resource is applied whose xds resource bytes are not valid protobuf JSON for anypb.Any (e.g. '@type' missing/incorrect, invalid field types), causing protojson to panic during UnmarshalJSON.
Common situations: Hand-writing CEC YAML/JSON with a wrong or missing @type in the Any payload; copy-pasted Envoy config that is plain Envoy JSON rather than protobuf-JSON; version mismatch where a field was renamed.
Related errors
- failed to marshal patch for node %s: %w
- failed to convert to unstructured (marshal): %w
- failed to convert to unstructured (unmarshal): %w
- failed to setup Envoy load balancer reconciler: %w
- failed to get CiliumEnvoyConfig for service: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/c0f6553d4fc1611d.
Report an issue: GitHub.