grpc/grpc-go · error
error parsing custom audit logger config: %v
Error message
error parsing custom audit logger config: %v
What it means
Raised by toProtos when anypb.New(typedStruct) fails while wrapping a custom audit logger's Config struct into a google.protobuf.Any. This is a protobuf marshalling failure on the user-supplied Struct — almost always caused by a malformed structpb.Struct (e.g. a null/invalid Value, a nil map where a struct is required) rather than by the name field.
Source
Thrown at authz/rbac_translator.go:318
}
allow.AuditCondition = v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition)
deny.AuditCondition = toDenyCondition(v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition))
}
for i, config := range options.AuditLoggers {
if config.Name == "" {
return nil, nil, fmt.Errorf("missing required field: name in audit_logging_options.audit_loggers[%v]", i)
}
if config.Config == nil {
config.Config = &structpb.Struct{}
}
typedStruct := &v1xdsudpatypepb.TypedStruct{
TypeUrl: typeURLPrefix + config.Name,
Value: config.Config,
}
customConfig, err := anypb.New(typedStruct)
if err != nil {
return nil, nil, fmt.Errorf("error parsing custom audit logger config: %v", err)
}
logger := &v3corepb.TypedExtensionConfig{Name: config.Name, TypedConfig: customConfig}
rbacConfig := v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
IsOptional: config.IsOptional,
AuditLogger: logger,
}
allow.LoggerConfigs = append(allow.LoggerConfigs, &rbacConfig)
deny.LoggerConfigs = append(deny.LoggerConfigs, &rbacConfig)
}
return allow, deny, nil
}
// Maps the AuditCondition coming from AuditLoggingOptions to the proper
// condition for the deny policy RBAC proto
func toDenyCondition(condition v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition) v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition {
// Mapping the overall policy AuditCondition to what it must be for the Deny and Allow RBACView on GitHub (pinned to 03255a9237)
Solutions
- Inspect the inner %v — anypb.New errors usually name the offending field or type.
- Replace the custom config with a minimal valid structpb (e.g. empty {}) to confirm the logger loads, then add fields back one at a time.
- Generate the config from a real structpb.Struct in Go rather than hand-writing JSON, to guarantee valid Value types.
- Check the logger extension's documented config schema for required nested types.
Example fix
// before: config has an illegal null-in-struct value
"config": { "fields": { "sink": { "nullValue": null } } }
// after:
"config": { "fields": { "sink": { "stringValue": "stderr" } } } Defensive patterns
Strategy: validation
Validate before calling
// Confirm the logger config is a valid structpb.Struct before the SDK
// tries to wrap it in an Any.
func validateLoggerConfigs(policyStr string) error {
var p struct {
AuditLoggingOptions struct {
AuditLoggers []struct {
Config *structpb.Struct `json:"config"`
} `json:"audit_loggers"`
} `json:"audit_logging_options"`
}
if err := json.Unmarshal([]byte(policyStr), &p); err != nil { return err }
for i, l := range p.AuditLoggingOptions.AuditLoggers {
if l.Config == nil { continue }
// round-trip through proto marshalling to mimic anypb.New
if _, err := anypb.New(&v1xdsudpatypepb.TypedStruct{Value: l.Config}); err != nil {
return fmt.Errorf("audit_loggers[%d]: invalid config: %v", i, err)
}
}
return nil
} Prevention
- Build logger configs from real Go structs, not hand-written JSON.
- Avoid null/Value mismatches in nested fields.
- Test minimal config first, add fields incrementally.
- Cross-check against the logger extension's documented schema.
When it happens
Trigger: An audit_loggers[].config value that, after being decoded into a structpb.Struct, cannot be serialized into a TypedStruct Any. anypb.New returns a non-nil error and the translator wraps it.
Common situations: Hand-crafting the logger config as raw JSON with illegal protobuf-struct values (e.g. a number where a struct is expected, deeply nested nulls); a serialization edge case when Config is left as a zero-valued struct in older protobuf versions; type mismatch between what the logger expects and what is supplied.
Related errors
- failed to parse AuditCondition %v. Allowed values {NONE, ON_
- missing required field: name in audit_logging_options.audit_
- %d: "name" is not present
- %d: %v
- failed to unmarshal policy: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/28e786929c5bd07d.
Report an issue: GitHub.