grpc/grpc-go · error

missing required field: name in audit_logging_options.audit_

Error message

missing required field: name in audit_logging_options.audit_loggers[%v]

What it means

Raised by toProtos while looping over audit_logging_options.audit_loggers[]: each audit logger entry MUST have a non-empty "name" (it becomes the TypedExtensionConfig name and the type-URL prefix for the logger). The %v is the logger index, pinpointing the offending entry.

Source

Thrown at authz/rbac_translator.go:307

// Parse auditLoggingOptions to the associated RBAC protos. The single
// auditLoggingOptions results in two different parsed protos, one for the allow
// policy and one for the deny policy
func (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {
	allow = &v3rbacpb.RBAC_AuditLoggingOptions{}
	deny = &v3rbacpb.RBAC_AuditLoggingOptions{}

	if options.AuditCondition != "" {
		rbacCondition, ok := v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition_value[options.AuditCondition]
		if !ok {
			return nil, nil, fmt.Errorf("failed to parse AuditCondition %v. Allowed values {NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW}", options.AuditCondition)
		}
		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,
		}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Open the audit_loggers array at the reported index and add a unique non-empty "name".
  2. Make sure the name matches the registered logger extension name your server expects.
  3. Validate the loggers array in a unit test before serving the policy.
  4. If you have no custom logger, drop the audit_loggers array rather than leaving placeholder entries.

Example fix

// before:
"audit_loggers": [ { "config": { ... } } ]   // missing name at index 0

// after:
"audit_loggers": [ { "name": "my-custom-logger", "config": { ... } } ]
Defensive patterns

Strategy: validation

Validate before calling

func validateLoggerNames(policyStr string) error {
    var p struct {
        AuditLoggingOptions struct {
            AuditLoggers []struct {
                Name   string          `json:"name"`
                Config json.RawMessage `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.Name == "" {
            return fmt.Errorf("audit_loggers[%d]: missing \"name\"", i)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: The policy JSON declares audit_loggers as an array but one element omits "name" or sets it to "". The `config.Name == ""` check inside the loop returns this error with the element's index.

Common situations: Adding a custom audit logger config and forgetting the name field; templating loggers from a list that didn't include a name attribute; assuming name is optional because Config is the meaningful field.

Related errors


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