{"record":{"id":"bbcffdcba327dcbe","repo":"grpc/grpc-go","slug":"missing-required-field-name-in-audit-logging-opti","errorCode":null,"errorMessage":"missing required field: name in audit_logging_options.audit_loggers[%v]","messagePattern":"missing required field: name in audit_logging_options\\.audit_loggers\\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/rbac_translator.go","lineNumber":307,"sourceCode":"// Parse auditLoggingOptions to the associated RBAC protos. The single\n// auditLoggingOptions results in two different parsed protos, one for the allow\n// policy and one for the deny policy\nfunc (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {\n\tallow = &v3rbacpb.RBAC_AuditLoggingOptions{}\n\tdeny = &v3rbacpb.RBAC_AuditLoggingOptions{}\n\n\tif options.AuditCondition != \"\" {\n\t\trbacCondition, ok := v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition_value[options.AuditCondition]\n\t\tif !ok {\n\t\t\treturn nil, nil, fmt.Errorf(\"failed to parse AuditCondition %v. Allowed values {NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW}\", options.AuditCondition)\n\t\t}\n\t\tallow.AuditCondition = v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition)\n\t\tdeny.AuditCondition = toDenyCondition(v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition))\n\t}\n\n\tfor i, config := range options.AuditLoggers {\n\t\tif config.Name == \"\" {\n\t\t\treturn nil, nil, fmt.Errorf(\"missing required field: name in audit_logging_options.audit_loggers[%v]\", i)\n\t\t}\n\t\tif config.Config == nil {\n\t\t\tconfig.Config = &structpb.Struct{}\n\t\t}\n\t\ttypedStruct := &v1xdsudpatypepb.TypedStruct{\n\t\t\tTypeUrl: typeURLPrefix + config.Name,\n\t\t\tValue:   config.Config,\n\t\t}\n\t\tcustomConfig, err := anypb.New(typedStruct)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"error parsing custom audit logger config: %v\", err)\n\t\t}\n\n\t\tlogger := &v3corepb.TypedExtensionConfig{Name: config.Name, TypedConfig: customConfig}\n\t\trbacConfig := v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{\n\t\t\tIsOptional:  config.IsOptional,\n\t\t\tAuditLogger: logger,\n\t\t}","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/authz/rbac_translator.go#L289-L325","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Open the audit_loggers array at the reported index and add a unique non-empty \"name\".","Make sure the name matches the registered logger extension name your server expects.","Validate the loggers array in a unit test before serving the policy.","If you have no custom logger, drop the audit_loggers array rather than leaving placeholder entries."],"exampleFix":"// before:\n\"audit_loggers\": [ { \"config\": { ... } } ]   // missing name at index 0\n\n// after:\n\"audit_loggers\": [ { \"name\": \"my-custom-logger\", \"config\": { ... } } ]","handlingStrategy":"validation","validationCode":"func validateLoggerNames(policyStr string) error {\n    var p struct {\n        AuditLoggingOptions struct {\n            AuditLoggers []struct {\n                Name   string          `json:\"name\"`\n                Config json.RawMessage `json:\"config\"`\n            } `json:\"audit_loggers\"`\n        } `json:\"audit_logging_options\"`\n    }\n    if err := json.Unmarshal([]byte(policyStr), &p); err != nil { return err }\n    for i, l := range p.AuditLoggingOptions.AuditLoggers {\n        if l.Name == \"\" {\n            return fmt.Errorf(\"audit_loggers[%d]: missing \\\"name\\\"\", i)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Require a unique name for every audit logger entry.","Drop the audit_loggers array when unused rather than leaving placeholders.","Match the name to the registered extension name.","Unit-test the policy load path in CI."],"tags":["authz","rbac","audit-logging","config","validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}