t8y2/dbx · error

ACL principal is required

Error message

ACL principal is required

What it means

createACLs validates each ACL entry and requires a non-empty principal (or 'subject') after stripping the optional 'User:' prefix. The error is thrown before any admin API call when an entry in the acls/ACL config array lacks a principal, because RocketMQ ACL subjects must identify a user.

Source

Thrown at agents/drivers/rocketmq/acl.go:115

	}
	ctx, cancel := context.WithTimeout(context.Background(), config.RequestTimeout)
	defer cancel()
	address, err := a.brokerAddressForName(stringValue(params, "brokerName"))
	if err != nil {
		return nil, err
	}
	entries, _ := params["acls"].([]any)
	for _, raw := range entries {
		entry, _ := raw.(map[string]any)
		if _, hasAccessKey := entry["accessKey"]; hasAccessKey || entry["secretKey"] != nil {
			if err := client.UpdatePlainAccessConfig(ctx, address, plainAccessConfig(entry)); err != nil {
				return nil, err
			}
			continue
		}
		subject := strings.TrimPrefix(stringValue(entry, "principal", "subject"), "User:")
		if subject == "" {
			return nil, fmt.Errorf("ACL principal is required")
		}
		resource := stringValue(entry, "resourceName")
		if resource == "" {
			resource = "*"
		}
		host := stringValue(entry, "host")
		if host == "" {
			host = "*"
		}
		decision := stringValue(entry, "permissionType")
		if decision == "" {
			decision = "ALLOW"
		}
		acl := aclWire{Subject: subject, Policies: []aclPolicyWire{{Entries: []aclEntryWire{{
			Resource: resource, Actions: []string{mapACLOperation(stringValue(entry, "operation"))},
			SourceIPs: []string{host}, Decision: decision,
		}}}}}
		body, marshalErr := json.Marshal(acl)

View on GitHub (pinned to c0390bff16)

Solutions

  1. Add a non-empty 'principal' (or 'subject') field to every ACL entry, e.g. "principal": "User:appReader"
  2. Fix key-name typos so the entry actually uses 'principal' or 'subject'
  3. Filter/validate entries in your config pipeline before dispatching createAcls

Example fix

// before
{"resourceName": "test-topic", "perms": ["PUB"]}
// after
{"principal": "User:appReader", "resourceName": "test-topic", "perms": ["PUB"]}
Defensive patterns

Strategy: validation

Validate before calling

for i, e := range entries {
    if strings.TrimPrefix(stringValue(e, "principal", "subject"), "User:") == "" {
        return fmt.Errorf("entry %d: principal is required", i)
    }
}

Type guard

func hasPrincipal(entry map[string]any) bool {
    return strings.TrimPrefix(stringValue(entry, "principal", "subject"), "User:") != ""
}

Prevention

When it happens

Trigger: Calling an ACL dispatch action whose entries array contains an object with no 'principal'/'subject' key, an empty string, or only the literal 'User:' prefix with nothing after it.

Common situations: Hand-written JSON/YAML ACL configs with a typo like 'pricipal' or 'user'; generating entries programmatically where the user field is empty; copying IAM-style configs that use 'subject' instead of 'principal'.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/4034863f0fd3eedb. Report an issue: GitHub.