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 RBAC

View on GitHub (pinned to 03255a9237)

Solutions

  1. Inspect the inner %v — anypb.New errors usually name the offending field or type.
  2. 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.
  3. Generate the config from a real structpb.Struct in Go rather than hand-writing JSON, to guarantee valid Value types.
  4. 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

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


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/28e786929c5bd07d. Report an issue: GitHub.